getter 违反了得墨忒耳定律吗?

Vin*_*igh 4 java getter law-of-demeter

想象有一种GameState类型使用 a GameContext(通过process方法):

abstract class GameState {
    public abstract void process(GameContext context);
}
Run Code Online (Sandbox Code Playgroud)

GameContext 将包含诸如玩家、商店等游戏必需的内容。

一个国家将获得它所需要的东西:

class CombatState extends GameState {
    public void process(GameContext context) {
        Player player = context.getPlayer();

        if(player.isAlive()) {
            //...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该语句player.isAlive()可以重写为context.getPlayer().isAlive()

我的问题

得墨忒耳法则规定,物体只能与直系亲属相互作用。这是否违反原则,如何解决?

对于要动态处理的每个状态,形式参数必须为所有可能的状态所接受。这使得严格传递对象所需的内容变得困难,这就是每个状态从“主要来源”获取其所需内容的原因。我觉得主要来源的内聚力非常低,因为 aShopState需要与 a 不同的数据CombatState

Pet*_*der 5

状态不是进程,进程就是进程。战斗是一个过程,活着是一种状态。

使用抽象名称process使得你需要打破德墨忒耳定律。

看这个例子:

class CombatProcess extends GameProcess {
    public void hit(Player puncher, Player beaten) {
        if (beaten.getState().isAlive()) {
           Weapon oneWeapon = one.getCurrentWeapon();
               ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

CombatProcess 中的所有内容都尽可能具体。

分析什么玩家与什么玩家战斗不是 CombatProcess 本身的责任!在战斗过程开始之前,你必须知道你的对手是谁。

编辑:

在这个答案的评论中,您写道:

如果我的状态位于 Set、List 或 Map 中,我将无法对这些状态进行多态处理,

这是绝对正确的。Hook /Anchor-Pattern是从 1996 年开始的,至今仍在 Windows 中广泛使用和荣耀(所谓的system-hooks)。不幸的是,由于一些批评,它没有进入 OOD 的前 10 名模式。这位批评者之一是:

...将流程的所有操作抽象为逻辑独立的钩子,然后锚定它们并正确地迭代它们并不容易。

我个人的观点是,Hook/Ancher-Pattern 在 1996 年是革命性的,并且在未来与 CDI(例如弹簧)的结合将是革命性的。

最后!你可以决定:

  1. 打破德墨忒尔法则。
  2. 放下钩/锚图案。
  3. 编写此处描述的解决方法。

  • 喜欢你直接切入命名问题的方式。为什么命名事物是计算机科学中的两个难题之一,这是一个很好的例子。 (2认同)