这种方法是否违反了得墨忒耳法?

时间:2011-11-24 10:42:35

标签: law-of-demeter

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

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

1 个答案:

答案 0 :(得分:2)

确实根据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。您提出的代码是一种潜在的解决方案。