设计模式六大原则之迪米特法则(最少知道原则)

迪米特原则(law of demeter LOD):最少知道原则(LeastKnowledge Principle 简写LKP),尽量降低类与类之间的耦合;

定义:一个对象应该对其他对象保持最少的了解。最早是在1987年由美国Northeastern University的Ian Holland提出。

  • 问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
  • 解决方案:尽量降低类与类之间的耦合。

 无论是面向过程编程还是面向对象编程,软件编程的总的原则都是:低耦合,高内聚

迪米特法则还有一个更简单的定义:只与直接的朋友通信每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。

举例:有一个集团公司,下属单位有分公司和直属部门,现在要求打印出所有下属单位的员工ID。先来看一下违反迪米特法则的设计。

//总公司员工 
class Employee{ private String id; public void setId(String id){ this.id = id; } public String getId(){ return id; } 
} //分公司员工 
class SubEmployee{ private String id; public void setId(String id){ this.id = id; } public String getId(){ return id; } 
} // 分公司经理 
class SubCompanyManager{ public List getAllEmployee(){ List list = new ArrayList(); for(int i=0; i<100; i++){ SubEmployee emp = new SubEmployee(); //为分公司人员按顺序分配一个ID emp.setId("分公司"+i); list.add(emp); } return list; } 
} // 总公司经理 
class CompanyManager{   public List getAllEmployee(){ List list = new ArrayList(); for(int i=0; i<30; i++){ Employee emp = new Employee(); //为总公司人员按顺序分配一个ID emp.setId("总公司"+i); list.add(emp); } return list; } public void printAllEmployee(SubCompanyManager sub){// 此处,分公司的员工和总公司经理不是直接“朋友”List list1 = sub.getAllEmployee(); for(SubEmployee e:list1){ System.out.println(e.getId()); } List list2 = this.getAllEmployee(); for(Employee e:list2){ System.out.println(e.getId()); } } 
} // 客户端  
public class Client{ public static void main(String[] args){ CompanyManager e = new CompanyManager(); e.printAllEmployee(new SubCompanyManager()); } 
}

现在这个设计的主要问题出在CompanyManager中,根据迪米特法则,只与直接的朋友发生通信,而SubEmployee类并不是CompanyManager类的直接朋友(以局部变量出现的耦合不属于直接朋友),从逻辑上讲总公司只与他的分公司耦合就行了,与分公司的员工并没有任何联系,这样设计显然是增加了不必要的耦合。按照迪米特法则,应该避免类中出现这样非直接朋友关系的耦合。修改后的代码如下:

class SubCompanyManager{ public List getAllEmployee(){ List list = new ArrayList(); for(int i=0; i<100; i++){ SubEmployee emp = new SubEmployee(); //为分公司人员按顺序分配一个ID emp.setId("分公司"+i); list.add(emp); } return list; } public void printEmployee(){ List list = this.getAllEmployee(); for(SubEmployee e:list){ System.out.println(e.getId()); } } 
} class CompanyManager{ public List getAllEmployee(){ List list = new ArrayList(); for(int i=0; i<30; i++){ Employee emp = new Employee(); //为总公司人员按顺序分配一个ID emp.setId("总公司"+i); list.add(emp); } return list; } public void printAllEmployee(SubCompanyManager sub){ sub.printEmployee(); List list2 = this.getAllEmployee(); for(Employee e:list2){ System.out.println(e.getId()); } } 
} 

修改后,为分公司增加了打印人员ID的方法,总公司直接调用来打印,从而避免了与分公司的员工发生耦合。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部