迪米特原则(Law of Demeter, LoD)是面向对象设计原则的一种,也叫最少知道原则。迪米特原则是1987年秋天由lan holland在美国东北大学一个叫做迪米特的项目设计提出的,它要求一个对象应该对其他对象有最少的了解,所以迪米特法则又叫做最少知识原则。
迪米特原则问题由来
类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
迪米特原则是什么
- 一个对象应该对其他对象保持最少的了解
- 这个原理的名称来源于希腊神话中的农业女神,孤独的得墨忒耳
迪米特原则目的是尽量降低类与类之间的耦合。
自从我们接触编程开始,就知道了软件编程的总的原则:低耦合,高内聚。无论是面向过程编程还是面向对象编程,只有使各个模块之间的耦合尽量的低,才能提高代码的复用率。低耦合的优点不言而喻,但是怎么样编程才能做到低耦合呢?那正是迪米特原则要去完成的。
迪米特原则通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。
迪米特原则还有一个更简单的定义:只与直接的朋友通信。
首先来解释一下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。
迪米特原则优点
- 使得软件更好的可维护性与适应性
- 对象较少依赖其它对象的内部结构,可以改变对象容器(container)而不用改变它的调用者(caller)
迪米特原则示例
通过老师要求班长告知班级人数为例,讲解迪米特原则。先来看一下违反迪米特法则的设计,代码如下
public class Student {
private Integer id;
private String name;
public Student(Integer id, String name) {
this.id = id;
this.name = name;
}
}
public class Teacher {
public void call(Monitor monitor) {
List<Student> sts = new ArrayList<>();
for (int i = 0; i < 10; i++) {
sts.add(new Student(i + 1, "name" + i));
}
monitor.getSize(sts);
}
}
public class Monitor {
public void getSize(List list) {
System.out.println("班级人数:" + list.size());
}
}
上面这个设计的主要问题出在 Teacher 中,迪米特原则要求只与直接的朋友发生通信,而 Student 类并不是 Teacher 类的直接朋友(以局部变量出现的耦合不属于直接朋友),从逻辑上讲 Teacher 只与 Monitor 耦合就行了,与 Student 并没有任何联系,这样设计显然是增加了不必要的耦合。按照迪米特原则,应该避免类中出现这样非直接朋友关系的耦合。修改后的代码如下:
public class Student {
private Integer id;
private String name;
public Student(Integer id, String name) {
this.id = id;
this.name = name;
}
}
public class Teacher {
public void call(Monitor monitor) {
monitor.getSize();
}
}
public class Monitor {
public void getSize() {
List<Student> sts = new ArrayList<>();
for (int i = 0; i < 10; i++) {
sts.add(new Student(i + 1, "name" + i));
}
System.out.println("班级人数" + sts.size());
}
}
将Student 从 Teacher 抽掉,也就达到了 Student 和 Teacher 的解耦,从而符合了迪米特原则。
迪米特原则的初衷是降低类之间的耦合,由于每个类都减少了不必要的依赖,因此的确可以降低耦合关系。但是凡事都有度,虽然可以避免与非直接的类通信,但是要通信,必然会通过一个“中介”来发生联系,例如本例中,老师(Teacher)就是通过班长(Monitor)这个“中介”来与 学生(Student)发生联系的。过分的使用迪米特原则,会产生大量这样的中介和传递类,导致系统复杂度变大。所以在采用迪米特法则时要反复权衡,既做到结构清晰,又要高内聚低耦合。
极客教程为大家详细介绍了面向对象的7大设计原则,可以参考