Suppose I have the following two classes to start off with:
public class Game {
private final Player self;
private final Player opponent;
public Game(final Player self, final Player opponent) {
this.self = Objects.requireNonNull(self);
this.opponent = Objects.requireNonNull(opponent);
}
}
public class Player {
private final String name;
public Player (final String name) {
this.name = Objects.requireNonNull(name);
}
}
Now I have discovered that I need access to the other players (thus to the Game
object) in my Player
class.
One way to do it is the following, add this to the Player
class:
private Game game;
public void setGame(final Game game) {
this.game = Objects.requireNonNull(game);
}
However now it breaks immutability of the game
object, are there ways to preserve immutabiity of mutually created objects?
Or do I need to resort to manually imposed mutability and safety (from a regular client perspective, not from a multithreaded synchronization perspective)? Such as throwing an exception whenever someone attempts multiple setGame
.
To summarize, this is the mutual dependency I am trying to solve:
Player playerSelf = new Player(/* non-existing game */, "Self");
Player playerOpponent = new Player(/* non-existing game */, "Opponent");
Game game = new Game(playerSelf, playerOpponent);
versus
Game game = new Game(/* non-existing player */, /* non-existing player */);
Player playerSelf = new Player(game, "Self");
Player playerOpponent = new Player(game, "Opponent");
Does there exist a Pattern such as for example the Builder Pattern which aids against an explosion of constructor arguments, which could be solved in a way that breaks immutability if one wanted to avoid the exposion without using the Builder Pattern?
Whenever you have a circular dependency, break it. It will help reduce your code's coupling, increase testability, and keep you sane. Why does Player
need access to the other player in the first place? You might be trying to put too much functionality into it. Perhaps you could move that into the Game
? Or into, say, a Strategy
that's inserted into the Player
object?
Also, bear in mind that immutability isn't always the answer. Some things, like the game state, are inherently mutable. Trying to shoehorn them into immutable objects is bound to make life miserable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With