德米特定律是什么?

Ano*_*ous 10 c# java oop law-of-demeter

让我们从维基百科开始:

更正式地说,函数的Demeter法则要求对象O的方法m只能调用以下类型对象的方法:

  1. O本身
  2. m的参数
  3. 在m中创建/实例化的任何对象
  4. O的直接组件对象
  5. 一个全局变量,可由O访问,范围为m

规则1:

public class ClassOne {

    public void method1() {
        method2();
    }

    public void method2() {

    }
}
Run Code Online (Sandbox Code Playgroud)

规则2:

public class ClassOne {

    public void method1(ClassTwo classTwo) {
        classTwo.method2();
    }
}

class ClassTwo {

    public void method2() {

    }
}
Run Code Online (Sandbox Code Playgroud)

规则3:

public class ClassOne {

    public void method1() {
        ClassTwo classTwo = new ClassTwo();
        classTwo.method2();
    }
}

class ClassTwo {

    public void method2() {

    }
}
Run Code Online (Sandbox Code Playgroud)

规则4(感谢@juharr):

public class ClassOne {

    private ClassTwo classTwo;

    public void method1() {
        classTwo = new ClassTwo();
        classTwo.method2();
    }
}

class ClassTwo {

    public void method2() {

    }
}
Run Code Online (Sandbox Code Playgroud)

规则5:

?
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮我处理规则5吗?


德米特定律是否意味着链接不好?

User.getName().getLastName();
Run Code Online (Sandbox Code Playgroud)

这导致高耦合.


不是"告诉,不要问"类似的原则吗?

这一切都是这样吗?我错了什么?你怎么能遵守得墨忒耳法?

Gho*_*ica 9

“告诉不要问”有点不同。

Demeter:不要为了得到什么而去做最后的事情。

TDA:不要从另一个对象检索“信息”然后对此做出决定。简单的例子:

if (someList.size() == 0) { bla
Run Code Online (Sandbox Code Playgroud)

if (someList.isEmpty()) { bla
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,您都在调用其他对象的方法;但有一个关键的区别:第一个调用向您公开了另一个对象的“内部”状态;然后你就可以做出一些决定。鉴于,在“TDA”改进的第二个版本中;您将“状态评估”留在该其他对象中;从而以某种方式减少耦合。

但仅供记录:第二个示例仍然根据该列表的状态做出决定。从这个角度来看,它只是比选项 1稍好的版本。理想情况下,您不需要此类检查。