Intro
Currently I have something of the form:
Tetris class ---> FallingPiece class ----> Piece class
A Piece
can be a Square
, a T
, etc. It has info about its shape and the shapes of its rotations, its size, etc.
The FallingPiece
class basically contains an attribute with a reference to a Piece
(the currently falling piece in the Tetris game) and will probably have its current (x, y)
location and its color.
My initial design was to have something of the form:
class Tetris {
private IPieceGenerator pieceGenerator;
private FallingPiece fallingPiece;
...
public Tetris(IPieceGenerator pieceGenerator) {
this.pieceGenerator = pieceGenerator;
...
}
private void someMethodThatNeedsAFallingPiece() {
if (fallingPiece == null) {
Piece piece = pieceGenerator.Generate();
fallingPiece = new FallingPiece(piece);
}
...
}
}
which of course has the problem that if I later want to Unit-Test my Tetris class and to know in which (x, y)
location of the board my current FallingPiece
is, I can't. I remember seeing this "problem" exposed in the fabulous Misko Hevery's The Clean Code Talks .
The first problem
seems to be that as I'm giving the Tetris
class the responsability of creating FallingPiece
objects, I can't then have a reference to them (I have passed through constructor injection a Piece
Factory, not FallingPiece
Factory!).
Now, I can see at least 2 ways to solve this:
- I could just define an
internal
(C#)/package-protected
(Java) getter for theFallingPiece
attribute, so I can easily test it. This might seem harmless, but I don't find it too elegant. - I could instead of passing it a
Piece
Factory, pass aFallingPiece
Factory. I could then control which objects would be returned by the Factory and access them through it. What do you guys think of this way? Is it commonly used?
Is there any other way of solving this?
There is a second problem
related to fact that I've originally implemented a FallingPiece
to be an immutable type. This means that every time I want to update the FallingPiece
's position on the Tetris
board, for example, I'll have to create a new FallingPiece
instance and the attribute on Tetris will now point to a new FallingPiece
. Which can be a big problem if I want, for example, to have access to the FallingPiece
reference through a FallingPieceFactory
that is passed to the Tetris
class. It appears to me that immutable data types can be if misused a lot of headache when trying to test classes, right? Or is this a bad use of an immutable datatype, in the first place?
Thanks