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 theFallingPieceattribute, 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
PieceFactory, pass aFallingPieceFactory. 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