迪米特法则 (LOD:Law of Demeter/Demeter Principle), 又叫最少知道原则(LKP:Least Knowledge Principle),即一个类对自己依赖的类知道的越少越好。
其实,迪米特法则反应出来的核心思想还是编程中总的原则:低耦合,高内聚。类与类关系越密切,耦合度越大,如果实际的需求发生改变,我们需要更改软件,当一个类改动时,另一个或多个类跟这个类的关系越密切(耦合度越高),受到的影响也越大。迪米特法则还有一个更简单的定义:只与直接的朋友通信。点击显 / 隐
直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖,关联,组合,聚合等。其中,我们称出现成员变量,方法参数,方法返回值中的类为直接的朋友,而出现在局部变量中的类不是直接的朋友。也就是说,陌生的类最好不要以局部变量的形式出现在类的内部。
举一个打印员工绩效的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
public class Demeterprinciple { public static void main(String[] args) { DevelopmentCenterManage.showPerformance(); }
private static class DevelopmentCenter{ private String name; private String performance;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPerformance() { return performance; }
public void setPerformance(String performance) { this.performance = performance; } }
private static class FirstDepartment{ private String name; private String performance;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPerformance() { return performance; }
public void setPerformance(String performance) { this.performance = performance; } }
private static class FirstDepartmentManager{ private static List<FirstDepartment> getFirstDepartment(){ List<FirstDepartment> firstDepartmentList = new ArrayList<FirstDepartment>(); FirstDepartment firstDepartment = new FirstDepartment(); firstDepartment.setName("zhangsan"); firstDepartment.setPerformance("A"); firstDepartmentList.add(firstDepartment); return firstDepartmentList; } }
private static class DevelopmentCenterManage{
private static List<DevelopmentCenter> getDevelopmentCenter(){ List<DevelopmentCenter> developmentCenterList = new ArrayList<DevelopmentCenter>(); DevelopmentCenter developmentCenter = new DevelopmentCenter(); developmentCenter.setName("zhangsan"); developmentCenter.setPerformance("A"); developmentCenterList.add(developmentCenter); return developmentCenterList; }
private static void showPerformance(){ List<DevelopmentCenter> developmentCenterList = getDevelopmentCenter(); for (DevelopmentCenter developmentCenter : developmentCenterList ){ System.out.println("name:"+ developmentCenter.getName() + " performance:"+ developmentCenter.getPerformance()); } List<FirstDepartment> firstDepartmentList = FirstDepartmentManager.getFirstDepartment(); for (FirstDepartment firstDepartment : firstDepartmentList) { System.out.println("name:"+ firstDepartment.getName() + " performance:"+ firstDepartment.getPerformance()); } } } }
|
在上面的例子中,我们想打印出开发中心所有员工的绩效情况,但是由于开发中心的开发一部员工普遍表现优秀,所以也想一起打印出来,但共用了 DevelopmentCenterManage 类的打印方法,最终导致引入了 DevelopmentCenterManage 的非直接朋友类 FirstDepartment,违反了迪米特法则,这样显然是增加了不必要的耦合。因此,改进如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
public class Demeterprinciple1 { public static void main(String[] args) { DevelopmentCenterManage.showPerformance(); }
private static class DevelopmentCenter{ private String name; private String performance;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPerformance() { return performance; }
public void setPerformance(String performance) { this.performance = performance; } }
private static class FirstDepartment{ private String name; private String performance;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPerformance() { return performance; }
public void setPerformance(String performance) { this.performance = performance; } }
private static class FirstDepartmentManager{ private static List<FirstDepartment> getFirstDepartment(){ List<FirstDepartment> firstDepartmentList = new ArrayList<FirstDepartment>(); FirstDepartment firstDepartment = new FirstDepartment(); firstDepartment.setName("zhangsan"); firstDepartment.setPerformance("A"); firstDepartmentList.add(firstDepartment); return firstDepartmentList; }
private static void showFirstDepartmentPerformance(){ List<FirstDepartment> firstDepartmentList = getFirstDepartment(); for (FirstDepartment firstDepartment : firstDepartmentList) { System.out.println("name:"+ firstDepartment.getName() + " performance:"+ firstDepartment.getPerformance()); } } }
private static class DevelopmentCenterManage{
private static List<DevelopmentCenter> getDevelopmentCenter(){ List<DevelopmentCenter> developmentCenterList = new ArrayList<DevelopmentCenter>(); DevelopmentCenter developmentCenter = new DevelopmentCenter(); developmentCenter.setName("zhangsan"); developmentCenter.setPerformance("A"); developmentCenterList.add(developmentCenter); return developmentCenterList; }
private static void showPerformance(){ List<DevelopmentCenter> developmentCenterList = getDevelopmentCenter(); for (DevelopmentCenter developmentCenter : developmentCenterList ){ System.out.println("name:"+ developmentCenter.getName() + " performance:"+ developmentCenter.getPerformance()); }
FirstDepartmentManager.showFirstDepartmentPerformance(); } } }
|
迪米特法则的核心是降低类之间的耦合,在实际开发的过程中,对于被依赖的类不管多么复杂,我们都应尽量将逻辑封装在类的内部,对外除了提供的 public 方法,不对外泄露任何信息。当然,这不是要求完全没有依赖关系,使用迪米特法则时我们应当根据实际情况权衡,尽量降低类间 (对象间) 耦合关系。
附:本次演示的项目地址
https://github.com/syshlang/java-design-principle