在这种情况下如何避免instanceof运算符

gra*_*hez 4 java oop polymorphism design-patterns

我正在编写简单的游戏,其中的细胞可以处于两种状态,由玩家自由拍摄.

interface Cell {
    int posX();
    int posY();
}

abstract class BaseCell implements Cell {

    private int x;
    private int y;

    public int posX() {
        return x;
    }

    public int posY() {
        return y;
    }

    ...
}

class FreeCell extends BaseCell {
}

class TakenCell extends BaseCell {
    private Player owningPlayer

    public Player owner() {
        return owningPlayer;
    }

}
Run Code Online (Sandbox Code Playgroud)

在每个回合中,我需要检查所有细胞以使用如下方法计算下一个细胞状态

// method in class Cell
public Cell nextState(...) {...}
Run Code Online (Sandbox Code Playgroud)

收集Set所有尚未服用的细胞.上面的方法返回,Cell因为单元格可能从Free变为Taken或相反.我正在做类似下面的事情来收集它们:

for (Cell cell : cells) {
    Cell next = cell.futureState(...);
    if(next instanceof FreeCell) {
        freeCells.add(currentCell);
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

它很丑.如何做到这一点,以避免这样的hacks实例?我不是在谈论另一个hack,而是想找出适当的OOP解决方案.

Gui*_*one 5

听起来你正在调情"状态"模式,但你并不完全在那里.使用状态模式,您将拥有Cell对象和"Cell State"类的层次结构.

Cell对象将使用组合而不是继承.换句话说,Cell将具有当前状态属性.如果你有一个Cell,其中currentState属性是一个FreeState对象,那么它就是一个空闲单元格.如果你有一个Cell,其中currentState属性是TakenState对象,那么它是一个自由状态.

如何做到这一点,以避免这样的hacks实例?

每当您遇到需要执行instanceof的情况时,都会向Cell类添加一个方法并调用它.Cell委托给当前状态.委托给当前状态的Cell中的代码实际上并不知道状态是什么.它只相信国家会做正确的事情.在FreeState和TakenState中,您提供了每种方法的实现,这些方法根据其状态执行正确的操作.