【问题标题】:Does this method call violate the Law Of Demeter?这个方法调用是否违反了得墨忒耳定律?
【发布时间】:2011-11-24 10:42:34
【问题描述】:

假设您有类似以下的内容(遗憾的是,我不允许发布原始代码):

public void foo() {
    MyObject obj = getMyObject();

    bar(obj);
}

public void bar(MyObject obj) {
   Type type = new Type(obj.getOtherObject());
}

foo 调用bar,传入obj。但是它没有使用obj,而是调用了一个getter来检索所需的信息。这违反得墨忒耳定律吗?

这样写会不会更好:

public void foo() {
    MyObject obj = getMyObject();

    bar(obj.getOtherObject());
}

public void bar(MyOtherObject otherObj) {
   Type type = new Type(otherObj);
}

【问题讨论】:

    标签: law-of-demeter


    【解决方案1】:

    确实根据Law of Demeter上的wiki:

    基本概念是给定对象应该假设 尽可能了解其他任何东西的结构或属性...

    您的bar 假设给定的MyObject(一种如此强耦合的具体类型,再次针对LoD)具有称为getOtherObject 的方法,因此您提出的解决方案对假设进行排序并使代码更接近于遵守LoD .你可以更进一步,提供bar 想要的类型:

    bar(new Type(obj.getOtherObject());

    根据您的语言,您可以不传递接口/合同而不是实体类型吗?这会将强耦合转变为松耦合。

    当然,如果这都是给定对象的内部内容,那么它可能不会破坏 LoD,因为它是“亲密朋友”:

    • 每个单元应该只对其他单元有有限的了解:只有与当前单元“密切”相关的单元。
    • 每个单位只能与朋友交谈;不要和陌生人说话。
    • 只与您的直系朋友交谈。

    在 OO 中,我认为您的原始代码基于此论点破坏了 LoD:

    ...对象 A 可以请求对象的服务(调用方法) 实例 B,但对象 A 无法“通过”对象 B 访问 另一个对象 C 请求它的服务。这样做意味着 对象 A 隐含地需要更多地了解对象 B 的内部 结构。

    在我看来,您似乎使用obj 来调用getOtherObj。您提出的代码是一个潜在的解决方案。

    【讨论】:

      猜你喜欢
      • 2023-04-04
      • 2019-04-30
      • 2011-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多