吸气剂违反了得墨忒耳法吗?

时间:2015-12-09 07:46:27

标签: java getter law-of-demeter

想象一下GameState类型使用了GameContext(通过process方法):

abstract class GameState {
    public abstract void process(GameContext context);
}

GameContext将包含播放器,商店等等对游戏至关重要的东西。

州可以访问所需的内容:

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

        if(player.isAlive()) {
            //...
        }
    }
}

声明player.isAlive()可以改写为context.getPlayer().isAlive()

我的问题

Demeter法则规定物体只应与直系亲属互动。这会违反原则吗?如何解决?

对于要动态处理的每个状态,所有可能状态都必须接受形式参数。 这使得很难将对象严格传递给它所需的,这就是为什么每个州从主要来源获取它所需要的东西"。我认为主要来源的内聚力非常低,因为ShopState需要的数据不同于CombatState

2 个答案:

答案 0 :(得分:4)

国家不是进程,进程是进程。打架是一个过程,活着就是一个国家。

使用process的抽象名称使您需要违反得墨忒耳定律。

看一下这个例子:

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

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

分析哪个玩家与哪个玩家战斗不是CombatProcess本身的责任!在CombatProcess开始之前,你必须知道你与谁对抗。

编辑:

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

  

如果我在Set,List或Map中有状态,我将无法对多态进行多态处理,

这绝对是正确的。 Hook/Anchor-Pattern是从1996年开始的,并且在Windows中仍被广泛使用和荣耀(所谓的system-hooks)。不幸的是,由于一些评论家,它确实找到了前往OOD十大模式的方式。其中一位评论家是:

  

...将进程的所有操作抽象为逻辑独立挂钩并随后将它们锚定并正确迭代它们并不容易。

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

最后!你可以决定:

  1. 违反得墨忒耳法则。
  2. 放下钩子/弓箭手模式。
  3. 撰写描述here
  4. 的解决方法

答案 1 :(得分:0)

由于分界定律是松散耦合的一个特例。

我认为它的工作方式是:

我们可以访问特定类及其方法的字段,即使我们链接多个方法(比方说)。我们在java中一直这样做,需要注意的是,链接仅适用于单个类的方法。

分隔符法律提醒我们不要一次访问多个类的对象和/或方法

示例:

如果我们有A,B,C类。

B类有一个持有A参考的字段,C有B的参考。

然后我们不应该通过使用getter获取A到C的引用,它有助于维护松散耦合。

同样,这是我认为它有效的方式。