迪米特法则
什么是迪米特法则
迪米特法则也被称为最少知识原则(Least knowledge Principle,LKP)也可以表述为 一个对象应该对其他对象有最少的了解,即一个类应该对自己需要耦合或调用的类知道的最少。
我们先看看它原汁原味的英文定义:
Each unit should have only limited knowledge about other units: only units “closely” related to the current unit. Or: Each unit should only talk to its friends; Don’t talk to strangers.
翻译过来就是:
每个模块(unit)只应该了解那些与它关系密切的模块(units: only units “closely” related to the current unit)的有限知识(knowledge)。或者说,每个模块只和自己的朋友“说话”(talk),不和陌生人“说话”(talk)。
理解迪米特法则
迪米特法则认为任何一个对象或者方法,它应该只能调用下列对象:
- 该对象本身
- 作为参数传进来的对象(也可以是该对象的字段)
- 在方法内创建的对象
迪米特法则用以指导正确的对象协作,分清楚哪些对象应该产生协作,哪些对象则对于该对象而言,又应该是无知的。
迪米特法则的意义
迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。
迪米特法则不希望类之间建立直接的联系。如果真的有需要建立联系,也希望能通过它的友元类来转达。因此,应用迪米特法则有可能造成的一个后果就是:系统中存在大量的中介类,这些类之所以存在完全是为了传递类之间的相互调用关系——这在一定程度上增加了系统的复杂度。
实例
明星由于全身心投入艺术,所以许多日常事务由经纪人负责处理,如与粉丝的见面会,与媒体公司的业务洽淡等。这里的经纪人是明星的朋友,而粉丝和媒体公司是陌生人,所以适合使用迪米特法则,其类图如图所示。
1 package principle; 2 public class LoDtest 3 { 4 public static void main(String[] args) 5 { 6 Agent agent=new Agent(); 7 agent.setStar(new Star("林心如")); 8 agent.setFans(new Fans("粉丝韩丞")); 9 agent.setCompany(new Company("中国传媒有限公司")); 10 agent.meeting(); 11 agent.business(); 12 } 13 } 14 //经纪人 15 class Agent 16 { 17 private Star myStar; 18 private Fans myFans; 19 private Company myCompany; 20 public void setStar(Star myStar) 21 { 22 this.myStar=myStar; 23 } 24 public void setFans(Fans myFans) 25 { 26 this.myFans=myFans; 27 } 28 public void setCompany(Company myCompany) 29 { 30 this.myCompany=myCompany; 31 } 32 public void meeting() 33 { 34 System.out.println(myFans.getName()+"与明星"+myStar.getName()+"见面了。"); 35 } 36 public void business() 37 { 38 System.out.println(myCompany.getName()+"与明星"+myStar.getName()+"洽淡业务。"); 39 } 40 } 41 //明星 42 class Star 43 { 44 private String name; 45 Star(String name) 46 { 47 this.name=name; 48 } 49 public String getName() 50 { 51 return name; 52 } 53 } 54 //粉丝 55 class Fans 56 { 57 private String name; 58 Fans(String name) 59 { 60 this.name=name; 61 } 62 public String getName() 63 { 64 return name; 65 } 66 } 67 //媒体公司 68 class Company 69 { 70 private String name; 71 Company(String name) 72 { 73 this.name=name; 74 } 75 public String getName() 76 { 77 return name; 78 } 79 }
一些理解
不该有直接依赖关系的类之间,不要有依赖;有依赖关系的类之间,尽量只依赖必要的接口。迪米特法则是希望减少类之间的耦合,让类越独立越好。每个类都应该少了解系统的其他部分。一旦发生变化,需要了解这一变化的类就会比较少。
参考链接
[1] https://zhuanlan.zhihu.com/p/36883436
[2] https://www.jianshu.com/p/081403a945dd
[3] https://www.jianshu.com/p/14589fb6978e