对象创建后只能赋非空值的字段如何处理(Java)

What to do with fields that can only be assigned non-null values after the object is created (Java)

假设我正在制作游戏:

public class Game {

    Board board;
    public ArrayDeque<Player> players;

    //Players can have 'knights' and the one with the largest number
    //is referenced by the game.
    public Player playerWithLargestArmy;

    ...

}

一开始,当这样的游戏初始化时,没有玩家可以拥有最大的军队(一个玩家只有在拥有一定数量的骑士后才能拥有'army')。我想为 playerWithLargestArmy 分配一个值,但我不确定是什么。我也不想使用 null 因为我可以只保留隐式赋值来做到这一点(无论如何使用 null 都是不好的做法)。

我正在找人向我解释如何解决这个问题。我查了工厂和建筑商,但我不确定他们是否处理这种延迟分配。对于上下文,每个玩家都有一个 int 字段,指定他们有多少骑士。

我可以用每个玩家的布尔值来解决这个问题,说明他们是否拥有最大的军队,但是你需要遍历所有玩家来找到那个玩家,这并不理想。即使就我而言,这不是一个巨大的牺牲,我仍然想知道以供将来参考。

这种情况有java.util.Optional<T>class

它有 isPresent()get()(以及其他几种)方法,使您能够检查对象是否存在并获取基础对象的实例。

例子

声明

 Optional<Player> playerWithLargestArmy = Optional.empty();

赋值

playerWithLargestArmy = Optional.of(newValue);

价值的使用

if(playerWithLargestArmy.isPresent()) {
    Player p = playerWithLargestArmy.get();
}

甚至更好

playerWithLargestArmy.map(p -> doSomethingWithIt(p));

仅当值存在时才会调用 doSomethingWithIt

空对象模式 https://en.wikipedia.org/wiki/Null_Object_pattern

public class Army {
    public static final Army NullArmy = new Army(0);
    private int size;

    public Army(int size) {
        this.size = size;
    }
}

现在创建新军队时,只需将初始值设置为Army.NullArmy即可。