迪米特法则(Law of Demeter,LoD)又叫作最少知识原则(Least Knowledge Principle,LKP),产生于 1987 年美国东北大学的一个名为迪米特的研究项目,由伊恩·荷兰提出,被 UML 创始者之一的布奇普及,后来又因为在经典著作《程序员修炼之道》提及而广为人知。迪米特法则的定义是:只与你的直接朋友交谈,不跟 “陌生人” 说话(Talk only to your immediate friends and not to strangers)。其含义是:如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。 迪米特法则中的 “朋友” 是指:当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等,这些对象同当前对象存在关联、聚合或组合关系,可以直接访问这些对象的方法。需要注意的是,过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。所以,在釆用迪米特法则时需要反复权衡,确保高内聚和低耦合的同时,保证系统的结构清晰。
① 降低了类之间的耦合度,提高了模块的相对独立性。 ② 由于亲合度降低,从而提高了类的可复用率和系统的扩展性。
学过 java 的应该都能看懂下面的代码,Client 通过 Data 的 getPersonList 方法获取了人员集合,然后将其遍历,这样写有没有问题呢?只看结果是没有问题的,但是它不符合迪米特法则。迪米特法则要求只跟朋友说话,其朋友指的是当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等。而 getPersonList 返回的集合中的 Person 并不是 Client 的朋友。
/**
* @author Demo_Null
* @version 1.0
* @date 2020/12/16 19:11
*/
public class Data {
public List<Person> getPersonList() {
return new ArrayList<Person>() {{
this.add(new Person("张三", 23));
this.add(new Person("李四", 24));
this.add(new Person("王五", 25));
}};
}
}
/**
* @author Demo_Null
* @version 1.0
* @date 2020/12/16 19:17
*/
public class Client {
public static void main(String[] args) {
Data data = new Data();
List<Person> personList = data.getPersonList();
for (Person person : personList) {
System.out.println(person);
}
}
}
我们想要的只是遍历人员,为什么要先把人员集合取出来自己去遍历呢?我们去指使 Data 类帮我们遍历不香么。于使我们将代码改为了如下形式,由创建人员集合的类去完成遍历操作,我们调用其暴露出来的遍历方法即可。是自己的就是自己的,在项目中有一些方法,放在本类中也可以,放在其他类中也没有错误。我们可以坚持这样一个原则:如果一个方法放在本类中,即不增加类间关系,也对本类不产生负面影响,就放置在本类中。
/**
* @author Demo_Null
* @version 1.0
* @date 2020/12/16 19:50
*/
public class Data {
public List<Person> getPersonList() {
return new ArrayList<Person>() {{
this.add(new Person("张三", 23));
this.add(new Person("李四", 24));
this.add(new Person("王五", 25));
}};
}
public void forList() {
List<Person> personList = this.getPersonList();
for (Person person : personList) {
System.out.println(person);
}
}
}
/**
* @author Demo_Null
* @version 1.0
* @date 2020/12/16 19:50
*/
public class Client {
public static void main(String[] args) {
Data data = new Data();
data.forList();
}
}
迪米特法则的核心观念就是类间解耦,弱耦合,只有弱耦合了以后,类的复用率才可以提高,其要求的结果就是产生了大量的中转或跳转类,类只能和朋友交流,朋友少了你业务跑不起来,朋友多了,你项目管理就复杂,这个就需要自己考量了。迪米特法则要求我们类间解耦,但是解耦是有限度的,除非是计算机的最小符号二进制的 0 和 1,那才是完全解耦,我们在实际的项目中时,需要适度的考虑这个法则,别为了套用法则而做项目,法则只是一个参考,违背了法则,也不会有人判你刑,项目也未必会失败。