2010-02-07 3 views
4

Comment adhéreriez-vous au principe "Dites, ne demandez pas" (dorénavant "le principe") dans le scénario simple suivant? Dans un jeu de Tetris, je conseil, des cours BlockGrid et assemblez pertinentes à l'exemple suivant:Comment penser "Dites, ne demandez pas" dans cet exemple simple?

public class Board 
{ 
    private var fallingPiece:Piece; 
    private var blockGrid:BlockGrid; 
    ... 
    public function moveFallingPiece(xDirection:int, yDirection:int):void 
    { 
     blockGrid.movePiece(fallingPiece, xDirection, yDirection); 
    } 
} 

Une fois fallingPiece est placé dans la rangée du bas de BlockGrid, il ne devrait plus être le « fallingPiece ». Ai-je raison de ne pas violer le principe de ce qui suit?

if(blockGrid.getPiecePosition(piece).y == 0) 
{ 
    fallingPiece = null; 
} 

Mais est-ce vraiment différent de cela, ce qui à mon avis enfreint clairement le principe? Je ne suppose pas que j'ai conçu ces relations de classe de la manière appropriée pour travailler avec le principe. S'il vous plaît des conseils sur un autre design si c'est ce qui me manque.


EDIT, Solution proposée:

je suis allé avec les réponses proposant "des commentaires de commande" par les événements. Le conseil indique à BlockGrid de déplacer une pièce. La méthode movePiece de BlockGrid distribue les événements MOVED_TO ou MOVE_FAILED en fonction du résultat, que Board peut écouter et utiliser pour déterminer si une pièce a cessé de tomber. N'hésitez pas à nous faire part de vos commentaires sur cette solution.

public class Board 
{ 
    ... 
    public function Board() 
    { 
     ... 
     blockGrid.addEventListener(PieceMoveEvent.MOVE_FAILED, onPieceMoveFailed); 
     ... 
    } 

    public function moveFallingPiece(xDirection:int, yDirection:int):void 
    { 
      blockGrid.movePiece(fallingPiece, xDirection, yDirection); 
    } 

    public function onPieceMoveFailed(event:MovePieceEvent):void 
    { 
     if(event.instance == currentlyFallingPiece && event.fromPosition.y != event.toPosition.y) 
     { 
      currentlyFallingPiece = null; 
     } 
    } 
+0

Comment ne pas demander ne dites pas au travail? –

+0

Voici une bonne référence pour "dire, ne demandez pas": http://www.pragprog.com/articles/tell-dont-ask – Dolph

Répondre

1

Je pense que, pour mieux suivre le tell, Do not Ask principe, vous devriez avoir blockGrid votre classe de notification lorsque fallingPiece Conseil a atteint son point de repos. Dans les deux scénarios ci-dessus, vous demandez à blockGrid si position.y de la pièce == 0 afin de déterminer si fallingPiece doit être null. Au lieu de cela, vous voulez que blockGrid indique à la classe Board que fallingPiece.y a frappé 0.

+0

effectivement les pièces ne devraient pas avoir de "logique" en eux, le conseil devrait dites-leur ce qu'il faut faire. –

0

Je m'attendrais à une classe représentant chaque forme (sans informations de position), un contrôleur contenant une forme, une position et une orientation, et une autre classe représentant la grille actuelle des formes "débarquées". La grille a atterri aurait une méthode

testLanded(shape, shapePosition, orientation) 

qui serait appelé avant/après chaque opération de déplacement de décider si la forme est de se joindre à la grille débarquées ou doit se déplacer et de rester comme la pièce qui tombe.

Je vais sur l'idée de ne pas donner des données à des objets qui ne devraient pas vraiment posséder ces données - mais je ne l'ai jamais mis en œuvre Tetris ...

+0

Intéressant, mais comment implémenteriez-vous testLanded sans interroger d'autres objets pour leur état? – Stiggler

+0

le landedGrid aurait probablement un tableau 2d où les blocs précédents ont atterri - un bloc cesserait d'être un bloc approprié à ce stade et deviendrait juste quelques couleurs dans cette grille. Ainsi, la grille débarquée consomme les blocs dans sa propre structure de données, elle a donc toutes les informations à portée de main pour savoir si le bloc actuel a atterri sur le paysage laissé par les blocs précédents – DaveC

1

Ce que vous cherchez est la programmation en fonction des événements. Vous avez besoin d'une interface Listener avec une méthode appelée .event() et une interface Event pour représenter les événements. Les objets seront enregistrés avec d'autres objets (rappels) dans l'interface de l'écouteur. Lorsque vous créez un morceau et une carte, ils doivent implémenter l'interface de l'écouteur. Ensuite, vous pouvez définir la carte avec registerListener (board); Ensuite, quand les choses se passent à l'intérieur de Piece, il passera en boucle à travers tous les écouteurs enregistrés et appellera .event (event) sur chacun d'eux. De même avec le tableau, appelez board.registerListener (pièce) chaque fois que vous créez un nouveau morceau, car il décide que les choses se passent, il peut dire à tous les auditeurs enregistrés ce qui s'est passé. Ensuite, vous pouvez dire à une pièce que l'objet Board ne décide plus de le faire. Voici l'obligatoire Wikipedia entry.

0

Vous devrez peut-être repenser votre conception.Est-ce que Board a vraiment besoin de suivre la chute de la pièce ou devrait-elle appartenir à BlockGrid? Repasser qui possède quel comportement. Conservez les informations de position sur votre classe Piece et demandez à votre classe Piece de conserver une instance de BlockGrid.

Vous pouvez alors essayer quelque chose comme ça dans votre classe conseil ...

public function moveFallingPiece(xDirection:int, yDirection:int):void 
{ 
    blockGrid.moveFallingPiece(xDirection, yDirection); 
} 

Ensuite, dans la méthode de moveFallingPiece de BlockGrid ...

public function moveFallingPiece(xDirection:int, yDirection:int):void 
{ 
    fallingPiece.move(xDirection, yDirection); 
} 

Dans la méthode de déplacement de pièces, ajoutez votre logique .. Pas sûr de toute la puissance de AS3, mais il serait logique d'utiliser des abstractions ici. (c'est-à-dire que votre classe Piece dépend de ITrackFallingPieces au lieu de BlockGrid et que BlockGrid implémente ITrackFallingPieces).

Bonne chance!

+1

Merci, j'apprécie les commentaires! Cependant, je ne sais pas si cela répond à ma question; L'appel de blockGrid.setFallingPiece depuis Piece semble être une mauvaise encapsulation. En ce qui concerne la conception, j'ai décidé de ne pas stocker d'informations de position sur Piece car cela permettrait la possibilité de deux pièces ayant la même position. BlockGrid était destiné à garder une trace des positions de la pièce sur une grille (peut-être mieux nommé PieceGrid); le concept de «tomber» semblait être une responsabilité de trop. – Stiggler

+0

Man, nous parlons d'un jeu Tetris ici, pas de l'équilibreur de carburant NASA en temps réel lattest. Refroidir. –

+0

À qui s'adresse ce commentaire? Mon objectif principal avec la question n'est pas de faire fonctionner un jeu Tetris, mais de mieux comprendre un principe de conception ... – Stiggler

Questions connexes