①一个对象应该对其他对象保持最少的了解
②类与类关系越密切,耦合度越大
③迪米特法则又叫最少知道原则,即一个类对自己依赖的类知道的越少越好(对于一类被依赖的类,不管是多么复杂,对外只提供方法即可,不去展现内部的具体实现)
④简单的定义就是:只与直接的朋友通信
直接的朋友:每个对象都会与其他的对象有耦合关系,只有两个对象只有有耦合关系我们就称这两个对象为朋友关系。耦合的方式很多,依赖、关联、组合、聚合等,其中,我们称出现的成员变量,方法参数,方法返回值中的类为直接朋友,而出现在局部变量中的类就不是直接的朋友。也就是说陌生的类,最好不要以局部变量的形式出现在类的内部
先看一段代码
1 import java.util.ArrayList; 2 import java.util.List; 3 4 //客户端 5 public class Demeter1 { 6 7 public static void main(String[] args) { 8 //创建了一个 SchoolManager 对象 9 SchoolManager schoolManager = new SchoolManager(); 10 //输出学院的员工id 和 学校总部的员工信息 11 schoolManager.printAllEmployee(new CollegeManager()); 12 13 } 14 15 } 16 17 18 //学校总部员工类 19 class Employee { 20 private String id; 21 22 public void setId(String id) { 23 this.id = id; 24 } 25 26 public String getId() { 27 return id; 28 } 29 } 30 31 32 //学院的员工类 33 class CollegeEmployee { 34 private String id; 35 36 public void setId(String id) { 37 this.id = id; 38 } 39 40 public String getId() { 41 return id; 42 } 43 } 44 45 46 //管理学院员工的管理类 47 class CollegeManager { 48 //返回学院的所有员工 49 public List<CollegeEmployee> getAllEmployee() { 50 List<CollegeEmployee> list = new ArrayList<CollegeEmployee>(); 51 for (int i = 0; i < 10; i++) { //这里我们增加了10个员工到 list 52 CollegeEmployee emp = new CollegeEmployee(); 53 emp.setId("学院员工id= " + i); 54 list.add(emp); 55 } 56 return list; 57 } 58 } 59 60 //学校管理类 61 62 //分析 SchoolManager 类的直接朋友类有哪些 Employee、CollegeManager 63 //CollegeEmployee 不是 直接朋友 而是一个陌生类,这样违背了 迪米特法则 64 class SchoolManager { 65 //返回学校总部的员工 66 public List<Employee> getAllEmployee() { 67 List<Employee> list = new ArrayList<Employee>(); 68 69 for (int i = 0; i < 5; i++) { //这里我们增加了5个员工到 list 70 Employee emp = new Employee(); 71 emp.setId("学校总部员工id= " + i); 72 list.add(emp); 73 } 74 return list; 75 } 76 77 //该方法完成输出学校总部和学院员工信息(id) 78 void printAllEmployee(CollegeManager sub) { 79 80 //分析问题 81 //1. 这里的 CollegeEmployee 不是 SchoolManager的直接朋友 82 //2. CollegeEmployee 是以局部变量方式出现在 SchoolManager 83 //3. 违反了 迪米特法则 84 85 //获取到学院员工 86 List<CollegeEmployee> list1 = sub.getAllEmployee(); 87 System.out.println("------------学院员工------------"); 88 for (CollegeEmployee e : list1) { 89 System.out.println(e.getId()); 90 } 91 //获取到学校总部员工 92 List<Employee> list2 = this.getAllEmployee(); 93 System.out.println("------------学校总部员工------------"); 94 for (Employee e : list2) { 95 System.out.println(e.getId()); 96 } 97 } 98 }
以上代码注释的很清楚,这边不需要再次解释了:强调一点:陌生的类,最好不要以局部变量的形式出现在类的内部;陌生的类,最好不要以局部变量的形式出现在类的内部;陌生的类,最好不要以局部变量的形式出现在类的内部
改善后
1 import java.util.ArrayList; 2 import java.util.List; 3 4 //客户端 5 public class Demeter1 { 6 7 public static void main(String[] args) { 8 System.out.println("~~~使用迪米特法则的改进~~~"); 9 //创建了一个 SchoolManager 对象 10 SchoolManager schoolManager = new SchoolManager(); 11 //输出学院的员工id 和 学校总部的员工信息 12 schoolManager.printAllEmployee(new CollegeManager()); 13 14 } 15 16 } 17 18 19 //学校总部员工类 20 class Employee { 21 private String id; 22 23 public void setId(String id) { 24 this.id = id; 25 } 26 27 public String getId() { 28 return id; 29 } 30 } 31 32 33 //学院的员工类 34 class CollegeEmployee { 35 private String id; 36 37 public void setId(String id) { 38 this.id = id; 39 } 40 41 public String getId() { 42 return id; 43 } 44 } 45 46 47 //管理学院员工的管理类 48 class CollegeManager { 49 //返回学院的所有员工 50 public List<CollegeEmployee> getAllEmployee() { 51 List<CollegeEmployee> list = new ArrayList<CollegeEmployee>(); 52 for (int i = 0; i < 10; i++) { //这里我们增加了10个员工到 list 53 CollegeEmployee emp = new CollegeEmployee(); 54 emp.setId("学院员工id= " + i); 55 list.add(emp); 56 } 57 return list; 58 } 59 60 //输出学院员工的信息 61 public void printEmployee() { 62 //获取到学院员工 63 List<CollegeEmployee> list1 = getAllEmployee(); 64 System.out.println("------------学院员工------------"); 65 for (CollegeEmployee e : list1) { 66 System.out.println(e.getId()); 67 } 68 } 69 } 70 71 //学校管理类 72 73 //分析 SchoolManager 类的直接朋友类有哪些 Employee、CollegeManager 74 //CollegeEmployee 不是 直接朋友 而是一个陌生类,这样违背了 迪米特法则 75 class SchoolManager { 76 //返回学校总部的员工 77 public List<Employee> getAllEmployee() { 78 List<Employee> list = new ArrayList<Employee>(); 79 80 for (int i = 0; i < 5; i++) { //这里我们增加了5个员工到 list 81 Employee emp = new Employee(); 82 emp.setId("学校总部员工id= " + i); 83 list.add(emp); 84 } 85 return list; 86 } 87 88 //该方法完成输出学校总部和学院员工信息(id) 89 void printAllEmployee(CollegeManager sub) { 90 91 //分析问题 92 //1. 将输出学院的员工方法,封装到CollegeManager 93 sub.printEmployee(); 94 95 //获取到学校总部员工 96 List<Employee> list2 = this.getAllEmployee(); 97 System.out.println("------------学校总部员工------------"); 98 for (Employee e : list2) { 99 System.out.println(e.getId()); 100 } 101 } 102 }
小结:迪米特法则的核心是降低类与类之间的耦合,但是并不是要求完全没有依赖关系