1
class Entity {
    // various fields and methods
}

class MobileEntity extends Entity {
    // various fields and methods
}

interface Consumer {
    public void consume(final Consumable c);
}

interface Consumable {
    public void onConsume(final Consumer c);
}

class Player extends MobileEntity implements Consumer {
    // Override methods, etc
    // Can consume
}

class Npc extends MobileEntity {
    // Cannot consume anything
}

class Food implements Consumable {
    public void onConsume(final Consumer c) {
        if (c instanceof Player) {
            healPlayer();
            removeFood(1);
        }
    }
}

很抱歉将所有代码放在首位,但我认为这对我来说更容易解释,并且如果你看到它也能让你理解。这是我正在开发的游戏。我遇到的问题是如何在不使用instanceof运算符的情况下处理消耗品(无论是食物还是饮料)。我想避免在 Food 类中设置具体类Player(因为最终可能会有数百种不同类型的 Food),但在每种情况下都有合同例外(这表明存在问题)。

并非所有实体实现都会有健康字段。他们可能会,但如果是这样,我需要将某些标记为“可攻击”,然后进行测试

void applyDamage(int damage) {
    if (attackable) {
        health -= damage;
    }
}

由于硬编码行为(引入新类的指标),这引入了新问题

我听说可能在类似的线程中使用访问者模式,但我认为它不适用于当前情况。

4

3 回答 3

3

由于 Player 实现了 Consumer,因此 Food 中的 onConsume 方法应该只调用 Consumer 上的 consume() 方法。在这种情况下,Player 版本的消费会做正确的工作。instanceof 不仅不好,而且在装饰对象时会失败。

于 2012-08-17T02:04:23.097 回答
2

您的 Consumer 有一个 consume() 方法,而 Player 是一个 Consumer,那么为什么不将 Consumable 传递给 Consumer?另一方面,Player、Npc 和 Food 似乎都是数据模型,因此您可能希望将任何业务逻辑(例如增加健康或移除食物)排除在所有模型之外。在这种情况下,您需要一组单独的类,它们知道当玩家消耗食物时该怎么做。

于 2012-08-17T02:05:10.990 回答
0

要么你有向后的逻辑——消耗品应该传递给消费者,消耗品应该有消费者可以调用的方法,或者所有消费者都应该实现消耗品可以调用的所有可能的方法,并做正确的事情,这可能什么都不是。

于 2012-08-17T02:07:18.113 回答