I have a Game
class that needs some resources that are produced by Generator
s classes. Every game has its own generators and because generators are heavy objects to instantiate, Game
keeps an object pool with instances. In every Generator I have methods like these:
private MapBoardGenerator(Game game) {
super(game);
}
public static MapBoardGenerator getInstance(Game game) {
MapBoardGenerator instance = game.getGenerator(MapBoardGenerator.class);
if (instance == null) {
instance = new MapBoardGenerator(game);
game.addGenerator(MapBoardGenerator.class, instance);
}
return instance;
}
This static method is almost identical in every class that extends Generator
.
What I want to do is provide a Supplier<MapBoardGenerator>
to game
so the controls will be made elsewhere and getInstance
method will simply be:
public static MapBoardGenerator getInstance(Game game) {
return game.getInstance(MapBoardGenerator.class, MapBoardGenerator::new);
}
Is something wrong if I pass a supplier that calls a private constructor? It's a university project and design matters a lot here.
Passing a private constructor as an instance of Supplier
does not break encapsulation, for the very reason that the constructor is passed as an instance of Supplier
. The receiver of the instance (in this case Game
) has no idea how the Supplier
is implemented, only that it fulfills the Supplier
interface. That's what Programming to an Interface is all about: even though the caller provides a concrete implementation, the receiver is only aware of the interface which the implementation fulfills. Encapsulation would be violated if the Game
knew the specific implementation that it was getting.
Note that passing a Supplier
to the Game
may or may not make sense in the larger context of your application, but at least it does not violate the encapsulation of MapBoardGenerator
.