迪米特法则来自于1987年美国东北大学(NortheasternUniversity)的一个名为 Demeter的研究项目。迪米特法则(Law of Demeter,LoD)又称为最少知识原则(LeastKnowledge Principle,LKP)。
该原则定义如下:
每一个软件单位对其他单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。
Each unit should have only limited knowledge about other units: only units “closely” related to the current unit
迪米特法则要求一个软件实体应当尽可能少地与其他实体发生相互作用。如果一个系统符合迪米特法则,那么当其中的某一个模块发生修改时就会尽量少地影响其他模块;与此同时,扩展会相对容易。应用迪米特法则可降低系统的耦合度,使类与类之间保持松散的耦合关系。
迪米特法则还有几种定义形式,包括不要和“陌生人”说话(Don’t talk to strangers)、只与你的直接朋友通信(Talk only to your immediate friends)等。在迪米特法则中,对于一个对象,其朋友包括以下几类:
任何一个对象如果满足上面的条件之一,就是当前对象的“朋友”,否则就是“陌生人”。
在应用迪米特法则时,一个对象只能与直接朋友发生交互,不要与“陌生人”发生直接交互。这样做可以降低系统的耦合度,一个对象的改变不会给太多其他对象带来影响。迪米特法则要求在设计系统时应该尽量减少对象之间的交互,如果两个对象之间不必彼此直接通信,那么这两个对象就不应当发生任何直接的相互作用,如果其中一个对象需要调用另一个对象的方法,可以通过“第三者”转发这个调用。简而言之,就是通过引入一个合理的“第三者”来降低现有对象之间的耦合度。
在将迪米特法则运用到系统设计中时要注意下面几点:
歌手明星Star最主要的精力在于创作和演唱,所以歌手的许多日常事务由经纪人Agent负责处理;例如,和粉丝Fans的见面会、和演艺公司Company的商演接洽等。所以,明星只用于其经纪人打交道而不用与粉丝、演艺公司直接来往。此处,经纪人是明星"朋友",而粉丝和演艺公司是明星的"陌生人"。

package com.lod01;
/**
* 原创作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class Fans {
private String name;
public String getName() {
return name;
}
public Fans(String name) {
this.name = name;
}
}

package com.lod01;
/**
* 原创作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class Company {
private String name;
public String getName() {
return name;
}
public Company(String name) {
this.name = name;
}
}

package com.lod01;
/**
* 原创作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class Star {
private String name;
public Star(String name) {
this.name = name;
}
public String getName() {
return name;
}
}

package com.lod01;
/**
* 原创作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class Agent {
private Star star;
private Fans fans;
private Company company;
public void setStar(Star star) {
this.star = star;
}
public void setFans(Fans fans) {
this.fans = fans;
}
public void setCompany(Company company) {
this.company = company;
}
// 粉丝见面
public void meeting() {
System.out.println(star.getName() + "和" + fans.getName() + "见面合影");
}
// 洽谈商演
public void business() {
System.out.println(star.getName() + "和" + company.getName() + "洽谈商演");
}
}

package com.lod01;
/**
* 原创作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class Test {
public static void main(String[] args) {
// 创建经纪人
Agent agent = new Agent();
// 创建明星
Star star = new Star("赵丽颖");
agent.setStar(star);
// 创建粉丝
Fans fans = new Fans("追星的富二代");
agent.setFans(fans);
// 创建演艺公司
Company company = new Company("芒果演艺公司");
agent.setCompany(company);
// 和粉丝见面
agent.meeting();
// 和演艺公司商谈业务
agent.business();
}
}
