避免使用OOP实例

时间:2012-08-17 01:58:45

标签: java oop instanceof

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;
    }
}

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

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

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

您的消费者有一个消费()方法而玩家是消费者,所以为什么不将消费品传递给消费者?另一方面,似乎Player,Npc和Food都是数据模型,因此您可能希望保留所有模型中的任何业务逻辑(例如增加健康状况或去除食物)。在这种情况下,您需要一组单独的类,这些类知道玩家消耗食物时该怎么做。

答案 2 :(得分:0)

要么你有逻辑向后 - 消耗品应该传递给消费者,消耗品应该有消费者可以调用的方法,或者所有消费者都应该实现消耗品可以调用它们的所有可能的方法,并且正确的事情,这可能一无所获。