7

如果类 A 与类 B、C 和 D 中的每一个都有唯一的交互,那么交互的代码应该在 A 中还是在 B、C 和 D 中?

我正在编写一个小游戏,其中许多对象可以与其他对象进行独特的交互。例如,一个EMP击中 asentry gun并禁用它。它也可以击中 agrenade并引爆它,它也可以击中 aplayer并施加减速效果。

我的问题是,这段代码应该放在 EMP 类中,还是分散在所有其他类中?我的直觉告诉我要多态地执行此操作,以便我只需告诉每个类处理它喜欢的 EMP 罢工,这将允许我添加更多项目并更改它们处理 EMP 的方式,而无需更改 EMP 代码。

但是,EMP 目前只与我的 50 个对象中的大约 4 个交互,因此用空的 RespondToEMP() 调用填充 46 个对象似乎是错误的。这似乎也有点不直观,如果我决定删除 EMP,我需要更改所有其他类,而 EMP 类本身最终会变得非常小。这也意味着如果我想改变 EMP 的行为方式,我需要查看所有不同的类以找到所有可能的用法。此外,如果 EMP 有一些通用效果,例如爆炸,那么这种效果肯定会在 EMP 代码中,远离所有其他将分发的效果。

4

5 回答 5

1

你是对的,有一个虚拟方法是一种代码味道。有几种方法可以解决这个问题:

如果您希望添加更多对象,则用于处理事件的 Switch 语句效果很好,因为您将避免在添加更多对象时修改事件:

enum Event { EMP, Bomb }

class SentryGun {
    void handleEvent(Event e) { switch(e) {
        case EMP: disable();
    }}
    void disable() {}
}
class Grenade {
    void handleEvent(Event e) { switch(e) {
            case EMP: detonate();
    }}
    void detonate() {}
}

如果您希望添加更多事件,那么访问对象的事件效果很好,因为您不必修改现在可以对该事件做出反应的每个对象:

class EMP {
    void hit(SentryGun object) {
        object.disable();
    }

    void hit(Grenade object) {
        object.detonate();
    }
}
于 2013-03-06T23:17:45.587 回答
1

您可能需要考虑http://en.wikipedia.org/wiki/Visitor_pattern。如果您有超过 2 件事一起互动,请查看我对管理对象间关系的回答

于 2013-03-06T22:09:16.617 回答
1

我的想法是这样sentry gungrenade并且player都应该实现一个通用接口来强制执行该方法RespondToEMP。这样,如果您稍后决定其他 46 个对象中的一个可以被 EMP 击中,您将知道实现此接口。

于 2013-03-06T17:24:18.233 回答
0

这不是最优雅的解决方案,但是您可以做的一件事是拥有一个您的对象扩展的基类,该基类具有事件的默认行为,并且如果有事情要做,对象可以覆盖它。

于 2013-03-06T21:53:12.073 回答
0

在您的情况下,您需要区分可以交互或不能交互的对象。有三个选项:

  • 具有可能为空实现的通用接口
  • 接口并检查对象是否实现它
  • 定义一些带有交互和反应的地图/表格

由于前两个在其他答案中出现,我将描述第三个选项。我们定义映射:Thing x Object -> Command。在这种情况下,EMP_hit 将是 Thing(也许名称可能更好..),可能包含有关其来源的信息。对象将是你的所有东西。命令类似于命令模式(参见http://en.wikipedia.org/wiki/Command_pattern)。我会将其存储在地图而不是表格中,以仅保留非空命令,并使用一些将在同一类的事物/对象之间共享的字符串 ID 以在此映射中找到正确的条目。

该解决方案的优点是您可以在某个配置文件中定义它或/并在运行时动态更改。无需重新编译即可更改配置

于 2013-03-06T23:51:43.897 回答