5

我正在为大学做一个项目,我们正在编写一个游戏。在这个游戏中,可能会出现多种效果,一种效果会影响另一种效果的行为。现在的一个想法是使用一种复合模式,起初它似乎是一个可靠的解决方案。这里最大的问题是效果的行为方式取决于它所耦合的效果,我们看到解决此问题的唯一方法是使用 .getClass() 或我们想不惜一切代价避免的 instanceof。

有哪些方法可以设计这个问题?

编辑(一个小例子):我没有明确的代码示例,但我将尝试通过以下示例进行澄清:

所以游戏中有手榴弹(很明显会爆炸并造成伤害),这种爆炸被视为“ExplosionEffect”。手榴弹所在的方格在运行时可能会发生电源故障(PowerfailureEffect)。ExplosionEffect 和 PowerfailureEffect 可以耦合,这会导致爆炸更强烈并造成更多伤害。ExplosionEffect 也可以与其他效果相结合,导致爆炸伤害的表现更加不同

4

4 回答 4

2

您可以使用访客设计模式。所有效果类都实现了一个效果接口。主类使用 Effect 接口方法询问 EffectB 类应该如何表现。EffectB类中Effect的方法的实现调用主类中正确的方法。

于 2013-04-24T09:58:45.753 回答
1

另一个界面怎么样。也许有各种Modifier效果实现的接口。这些修饰符可以做诸如“增加爆炸力”之类的事情。您可以instanceof查看该类是否实现了修饰符,然后一个效果可以修改另一个效果。

注意:在instanceof接口上做一个是完全可以接受的——你不是在确定它是否可以根据它是什么来做某事,而是根据它所拥有的 API。

于 2013-04-24T10:14:23.223 回答
0
public void test(){
    methodForWaterEffect(new WaterEffect());
    combinationAttack1(new FireEffect(), new WaterEffect());
}

interface Effect{
    public void activateEffect();
}

class FireEffect implements Effect{

    @Override
    public void activateEffect() {
        System.out.println("Fire!");
    }

}

class WaterEffect implements Effect{

    @Override
    public void activateEffect() {
        System.out.println("Water!");
    }

}
public void combinationAttack1(FireEffect fe, WaterEffect we){
    //your algorithm here

}

public void methodForWaterEffect(WaterEffect fe){
    fe.activateEffect();
}

我有一个非常简单的建议。为什么不为每个实现名为 Effect 的接口的效果创建类。此外,如果您正在尝试模拟组合攻击,为什么不为这些组合攻击中的每一个创建函数呢?

所以在你的例子中,它将是

public void combination2(PoisonEffect pe, PowerFailureEffect pf){

}

这可能看起来工作量很大,但我认为这很好地解耦了您的代码,以后您可能会发现管理代码更容易。

请注意,为简单起见,它们不在单独的类文件中 =D。

于 2013-04-24T10:31:55.190 回答
-1

一个常见的反模式是使用类型检查,例如 with instanceof,而不是多态性。这是一个简单的例子。

public class Shape {
    public void draw() {
        if (this instanceof Square) {
            // Draw a square
        } else if (this instanceof Circle) {
            // Draw a circle
        }
    }
}

public class Square extends Shape {
    // ...
}

public class Circle extends Shape {
    // ...
}

请注意,draw()在 class 中的方法中Shape,我们通过查看当前对象的类型来确定要绘制的内容,然后执行相应的代码。这有几个缺点:类Shape需要知道它的所有子类,如果你想添加一个新的形状,你也必须修改类Shape。通过覆盖子类中的方法,使用多态性要好得多draw()

public abstract class Shape {
    public abstract void draw();
}

public class Square extends Shape {
    public void draw() {
        // Draw a square
    }
}

public class Circle extends Shape {
    public void draw() {
        // Draw a circle
    }
}

这样,类Shape不需要知道它的所有子类,你不需要修改Shape来添加一个新的形状,并且属于一个特定形状的所有逻辑都在它所属的地方(那个形状的类) .

于 2013-04-24T09:59:38.853 回答