Java 设计模式-强制子类的某些行为
有一个设计模式问题(一些与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) ,, 等 玩家应该在每一步之间收到反
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;
}
}