since I just lost one of my test runs on the server due to a mistake I made that was related to the PieceFactory, I would like to know what the rationale was in creating this interface? Why exactly are there seven (!) methods, one for each tetromino? How about something like this instead?
Piece get(PieceType pieceType);
The way it is right now is clunky and forces me to create a helper function in my test folder that takes a PieceType and a PieceFactory and produces the corresponding tetromino via a switch over all values of PieceType. (= waste of time and unnatural on top of that)
What are the upsides of doing it the way the given interface does it?
Both approaches are possible.
If one wants to generate a specific piece it might be slightly faster to have individual methods.
But this time difference is negligible and a good compiler should optimize this away with a bit of partial evaluation.
Due to the syntax, the approach with one method and switch (do not use an if-cascade here) might be smaller, and therefore, faster to write.
From a user point of view, a modern IDE with IntelliSense should take care of details such that neither of the methods is harder or more error-prone than the other if done correctly.
Depending on the inner content one might have to think about where code refactoring and sharing of common code is easier. But this should also be quite similar in both settings.
Therefore, the only real difference is in how one views pieces.
Is a piece one object with different characteristics depending on the type? Then a parametric factory method would be the right approach.
Alternatively, one could view each piece as an individual object and create a new factory method for each.
In general, factory methods replace constructors and should be for one distinct object.
In the approach of only one parametric method that takes the type, one would probably make this the constructor of a Piece class instead of having a degenerated factory with only one or two methods.
But then one should consider that the user might also want to construct pieces in another way (non-default rotation for instance). In this case, a constructor that only generates default pieces would be confusing.