Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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_Oop_Design Patterns_Interface_Abstract Class - Fatal编程技术网

允许单元';在Java中使用设计模式攻击地面、空中或两者的能力

允许单元';在Java中使用设计模式攻击地面、空中或两者的能力,java,oop,design-patterns,interface,abstract-class,Java,Oop,Design Patterns,Interface,Abstract Class,我正在制作一个有抽象战士类的文本游戏。在Fighter中,我有一个名为protected boolean isGround的变量。然后我有两个抽象类,它们扩展了名为AirFighter和GroundFighter的Fighter,基本上将isGround设置为True或False,这取决于它们是否是地面单位 然后我想设置游戏,以便在我的战斗阶段,游戏检查玩家1的速度是否比玩家2快,并且取决于谁比玩家2快,比如p1.攻击(p2),并打印出该战斗的统计数据,比如每个玩家的剩余生命值或类似的东西 我想

我正在制作一个有抽象战士类的文本游戏。在Fighter中,我有一个名为protected boolean isGround的变量。然后我有两个抽象类,它们扩展了名为AirFighter和GroundFighter的Fighter,基本上将isGround设置为True或False,这取决于它们是否是地面单位

然后我想设置游戏,以便在我的战斗阶段,游戏检查玩家1的速度是否比玩家2快,并且取决于谁比玩家2快,比如p1.攻击(p2),并打印出该战斗的统计数据,比如每个玩家的剩余生命值或类似的东西

我想让一些飞机攻击空中,或者攻击空中和地面,我想让一些地面战斗机只攻击地面,或者地面和空中。在保持松散耦合的同时,我该如何做呢?这是一个设计模式的类,它让我感到沮丧。有没有一种设计模式可以帮我解决这个问题


想想《星际争霸》,这就是我的游戏所模仿的,像海军陆战队这样的特定单位可以攻击地面和空中,一些空中单位只能攻击空中,一些可以同时攻击地面和空中。我希望能够做到这一点,而不会有一些讨厌的,如果其他检查声明

一个简单的方法是在基本
战斗机
中有一个方法,可以用来检查该
战斗机
是否可以攻击其他战斗机:

public abstract class Fighter {
    public abstract boolean isGround ();
    public abstract boolean canAttack (Fighter target);
}
然后,子类可以覆盖
canAttack
,并做出适当的决定。例如:

public class SurfaceToAirLauncher extends Fighter {
    @Override public boolean isGround () {
        // missile launcher is on the ground
        return true; 
    }
    @Override public boolean canAttack (Fighter target) {
        // we can only attack air targets
        return (target != null && !target.isGround());
    }
}

public class Dragon extends Fighter {
    @Override public boolean isGround () {
        // dragons are in the air
        return false; 
    }
    @Override public boolean canAttack (Fighter target) {
        // dragons can attack every target.
        return (target != null);
    }
}

public class Knight extends Fighter {
    @Override public boolean isGround () {
        // knights are on the ground
        return true; 
    }
    @Override public boolean canAttack (Fighter target) {
        // knights can only attack dragons
        return (target != null && target instanceof Dragon);
    }
}

如果知道
target
永远不会为
null
,则可以删除对
null
的检查。为了完整起见,我把它包括在内。

我建议使用装饰图案。您有一个SimpleFighter作为基类(它有一个canAttack(Fighter敌军)方法,只返回false),还有一个FighterDecorator,两者都实现了Fighter接口。请参见此处如何设置构造函数和委派方法:

然后有两个类扩展FighterCorator:

具有canAttack()方法的GroundKillerDecorator,该方法表示:

if(enemy.isGround) return true; else return super.canAttack();
if(!enemy.isGround) return true; else return super.canAttack();
AirKillerDecorator具有canAttack()方法,该方法表示:

if(enemy.isGround) return true; else return super.canAttack();
if(!enemy.isGround) return true; else return super.canAttack();

这样你就可以像这样组成你的战士

new GroundKillerDecorator( new AirKillerDecorator( new SimpleFighter() ))

最理想的情况是,你可以用另外两个类代替SimpleFighter,它们实现不同的基本行为(而不是默认情况下不能攻击任何东西),但仍然实现相同的战斗机界面。

这篇文章标题太棒了。谢谢!这很有帮助,虽然我不认为它使用了任何模式,但它比我以前使用的更好。也许是战略模式?我喜欢称之为“常识模式”。并不是所有的东西都必须被标记为某种模式。程序员称之为“模式”,因为这是一种简单的方式,可以让我们向其他程序员传达我们的经验,即哪些技术工作得很好。使用最好的工具来完成这项工作。专注于保持代码的精确性、清晰性、可重用性和可维护性。不要仅仅为了使用“模式”而专注于使用“模式”。您的具体情况非常简单,一个具有常用方法的基类就足够了——不要过于复杂,这样您就可以将代码标记为某种“模式”。(并不是说您所问的问题不可理解;在学习过程中,完全有理由关注熟悉的事物,例如“模式”的概念)--我认为这里适用的陈词滥调是“当你只有一把锤子时,每个问题看起来都像钉子。”)谢谢你的回答,在我阅读你的解决方案之前,我已经用上面的解决方案解决了我的问题,但你的也可以,装饰器允许你在运行时动态地定义子类,而不是被锁在编译时定义中。OP没有任何这样的需求,这只会用一堆委托方法混淆代码,而没有任何实际的设计好处。OP没有装饰者想要解决的问题。回想一下OP的问题是,他想要避免一个大的、扭曲的
if
语句——这只不过是子类化有用性的一个经典例子。保持简单!完全正确。首先简单。昨晚很晚才有了“设计模式”的想法,但继承也是一种设计模式。