Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 设计模式-强制子类的某些行为_Java_Inheritance_Design Patterns - Fatal编程技术网

Java 设计模式-强制子类的某些行为

Java 设计模式-强制子类的某些行为,java,inheritance,design-patterns,Java,Inheritance,Design Patterns,有一个设计模式问题(一些与Java相关的术语,这是我当前的项目) 代码的当前布局: class Game - holds game state and manages logic, Super abstract class Player 玩家有不同类型玩家(AI、人类等)的子类 每个玩家最多可以进行三次移动(A、B、C),但必须按顺序进行。因此,玩家可以在轮到他们时选择以下任何移动顺序: (A、B), (B、C), (A、B、C) (A、C), (a) ,, 等 玩家应该在每一步之间收到反

有一个设计模式问题(一些与Java相关的术语,这是我当前的项目)

代码的当前布局:

class Game - holds game state and manages logic,

Super abstract class Player 
玩家有不同类型玩家(AI、人类等)的子类

每个玩家最多可以进行三次移动(A、B、C),但必须按顺序进行。因此,玩家可以在轮到他们时选择以下任何移动顺序: (A、B), (B、C), (A、B、C) (A、C), (a) ,, 等

玩家应该在每一步之间收到反馈,以便他们可以决定是执行另一步还是结束回合。 假设类型为抽象播放器,我有两种设计:

解决方案1: 对于集合中的所有玩家,请调用player.takeTurn(游戏)。因此,每个玩家都知道何时轮到他们,并且他们有一个对当前游戏对象的引用。takeTurn()返回时,他们的回合结束。Player.takeTurn被Player的所有子类覆盖。在该方法中,任何想要执行移动的玩家都可以引用传入的游戏对象。例如:

    game.makeMoveA(),
    game.makeMoveB(),
    etc
Game.makeMove()可以返回ok/error值来告诉玩家该移动是否合法。此外,更新后的游戏状态可由仍在takeTurn()方法范围内的游戏对象使用。 问题是,您依赖于所有子类来记住调用makeMove(),如果它们不调用,或者如果它们以错误的顺序调用,该怎么办?我想,异常/错误消息可能会处理错误顺序的调用方法,但我们仍然存在一个问题,即没有任何东西强制实例化的类实际响应和移动

解决方案2: 抽象类Player包含三个抽象方法getMoveA getMoveB和getMoveC。 因此,所有继承者都必须实现这些方法。 抽象超类播放器包含一个方法takeTurn()

这很好,因为行为被强制执行,但现在我们有一个棘手的问题,即如何向做出动作的球员提供反馈。如果这是一个非法的移动,等等。你可以强制执行另一个方法handleOverResponse(),但是每个玩家都必须跟踪成功/错误消息所指的移动

有什么想法吗?我很想听听你对此的看法


非常感谢

在我看来,您是在尝试让您的需求符合某个模式,而不是在看到模式之前分解需求

实现您的需求的一次简短尝试产生了这一点。这里有一个
策略
模式和一个
模板
模式,似乎没有您提到的问题

enum Move {

    A, B, C;
}

class Strategy {

    final List<Move> moves;

    public Strategy(List<Move> moves) {
        // TODO: Make sure it is valid.
        this.moves = moves;
    }
}

class Game {

}

abstract class Player {

    // Call before each move.
    abstract Strategy getStrategy(Game game);

    void move(Game game, Move move) {
        // By default do nothing.
    }
}

/**
 * The rules control the game.
 */
class Rules {

    public void play(Game game, Player player) {
        while (!gameOver(game)) {
            Strategy strategy = player.getStrategy(game);
            for (Move move : strategy.moves) {
                player.move(game, move);
                // Do your feedback here.
            }
        }
    }

    private boolean gameOver(Game game) {
        return false;
    }
}
枚举移动{
A、 B,C;
}
阶级策略{
最后的名单移动;
公共战略(列表移动){
//TODO:确保它是有效的。
this.moves=移动;
}
}
班级游戏{
}
抽象类玩家{
//每次移动前都要打电话。
抽象策略(博弈);
无效移动(游戏,移动){
//默认情况下什么都不做。
}
}
/**
*规则控制游戏。
*/
课堂规则{
公开无效游戏(游戏,玩家){
当(!游戏结束(游戏)){
策略=玩家.getStrategy(游戏);
for(Move-Move:strategy.moves){
玩家移动(游戏,移动);
//在这里做你的反馈。
}
}
}
私有布尔gameOver(游戏){
返回false;
}
}

您是否在寻找@Jayan,所以这正是我在第二个解决方案中提出的,但我已经说明了一些问题,如果这是可能的话,需要解决这些问题。您是否在为这些
播放器
类编写代码?如果他们行为不正确,这是一个错误吗?或者,您是否接受可能故意行为不当的第三方实现?你想保护自己不受什么伤害?根据答案,将应用完全不同的解决方案。看起来很有趣。对不起,我可以澄清一下,Player.move方法只是为了让玩家能够得到响应吗?此外,请记住,玩家应该有机会根据之前的反馈决定是否执行下一步。例如,玩家可以选择移动A(例如掷骰子),得到一个坏结果,然后选择不移动B。@SaadAttieh也许你可以在你的策略中提供一个移除方法。
enum Move {

    A, B, C;
}

class Strategy {

    final List<Move> moves;

    public Strategy(List<Move> moves) {
        // TODO: Make sure it is valid.
        this.moves = moves;
    }
}

class Game {

}

abstract class Player {

    // Call before each move.
    abstract Strategy getStrategy(Game game);

    void move(Game game, Move move) {
        // By default do nothing.
    }
}

/**
 * The rules control the game.
 */
class Rules {

    public void play(Game game, Player player) {
        while (!gameOver(game)) {
            Strategy strategy = player.getStrategy(game);
            for (Move move : strategy.moves) {
                player.move(game, move);
                // Do your feedback here.
            }
        }
    }

    private boolean gameOver(Game game) {
        return false;
    }
}