1. 程式人生 > 實用技巧 >第六節:迪米特法則

第六節:迪米特法則

迪米特原則(Demeter Principle)

一、基本介紹

  1、一個物件應該對其他物件保持最少的瞭解;

  2、類與類關係越密切,耦合度越大;

  3、迪米特法則(Demeter Principle)又叫最少知道原則,即一個類對自己依賴的類知道的越少越好。也就是說,對於被依賴的類不管多麼複雜,都儘量將邏輯封裝在類的內部。對外處了提供 public 方法,不對外洩漏任何資訊;

  4、迪米特法則還有個簡單的定義:只與直接的朋友通訊;

  直接朋友:每個物件都會與其他物件有耦合關係,只要兩個物件之間有耦合關係,我們就說這個兩個物件之間是朋友關係。耦合的方式很多,依賴,關聯,組合,聚合等。

       其中,我們稱出現在成員變數、方法引數,方法返回值中的類為直接的朋友

,而出現在區域性變數中的類不是直接的朋友。也就說說,陌生的類最好不要以區域性變數的形式出現在類的內部。

  

二、應用案例

  1、需求說明

    有一個學校,下屬有各個學院和總部,現要求打印出學校總部員工 ID和學院員工的 ID。

    

  2、方式一

    程式碼實現:

 1 public class Demeter1 {
 2     //客戶端,使用
 3     public static void main(String[] args) {
 4         SchoolManager schoolManager = new SchoolManager();
 5         schoolManager.printAllEmployee(new
CollegeManager()); 6 } 7 } 8 9 /** 10 * 學校總部員工 11 */ 12 class Employee { 13 private String id; 14 15 public void setId(String id) { 16 this.id = id; 17 } 18 19 public String getId() { 20 return id; 21 } 22 } 23 24 /** 25 * 學院的員工 26 */ 27 class CollegeEmployee {
28 private String id; 29 30 public void setId(String id) { 31 this.id = id; 32 } 33 34 public String getId() { 35 return id; 36 } 37 } 38 39 /** 40 * 管理學院員工的管理類 41 */ 42 class CollegeManager { 43 //返回學院的所有員工 44 public List<CollegeEmployee> getAllEmployee() { 45 List<CollegeEmployee> list = new ArrayList<CollegeEmployee>(); 46 for (int i = 0; i < 10; i++) { 47 CollegeEmployee emp = new CollegeEmployee(); 48 emp.setId("學院員工id= " + i); 49 list.add(emp); 50 } 51 return list; 52 } 53 } 54 55 /** 56 * 學校的管理類 57 * 分析: 58 * 直接朋友類:Employee、CollegeManager 59 * 間接朋友類:CollegeEmployee,是一個陌生類,違反了迪米特法則 60 */ 61 class SchoolManager { 62 //返回學校總部的員工 63 public List<Employee> getAllEmployee() { 64 List<Employee> list = new ArrayList<Employee>(); 65 66 for (int i = 0; i < 5; i++) { 67 Employee emp = new Employee(); 68 emp.setId("學校總部員工id= " + i); 69 list.add(emp); 70 } 71 return list; 72 } 73 74 //輸出學校總部和學院員工的資訊 75 void printAllEmployee(CollegeManager sub) { 76 77 /* 分析: 78 1、CollegeEmployee 不是 SchoolManager 的直接朋友 79 2、CollegeEmployee 是以佈局變量出現在 SchoolManager 80 3、違反了迪米特法則 81 */ 82 List<CollegeEmployee> list1 = sub.getAllEmployee(); 83 System.out.println("------------學院員工------------"); 84 for (CollegeEmployee e : list1) { 85 System.out.println(e.getId()); 86 } 87 List<Employee> list2 = this.getAllEmployee(); 88 System.out.println("------------學校總部員工------------"); 89 for (Employee e : list2) { 90 System.out.println(e.getId()); 91 } 92 } 93 }

    分析:

    (1)前面設計的問題在於 SchoolManager 中,CollegeEmployee 類並不是 SchoolManager 類的直接朋友;

    (2)按照迪米特法則,應該避免類中出現這樣非直接朋友的耦合;

    (3)對程式碼按照迪米特法則,進行改進;

  3、方式二

    程式碼實現:

 1 public class Demeter1 {
 2     //客戶端,使用
 3     public static void main(String[] args) {
 4         System.out.println("~~~使用迪米特法則的改進~~~");
 5         SchoolManager schoolManager = new SchoolManager();
 6         schoolManager.printAllEmployee(new CollegeManager());
 7     }
 8 }
 9 
10 /**
11  * 學校總部員工
12  */
13 class Employee {
14     private String id;
15 
16     public void setId(String id) {
17         this.id = id;
18     }
19 
20     public String getId() {
21         return id;
22     }
23 }
24 
25 /**
26  * 學院的員工
27  */
28 class CollegeEmployee {
29     private String id;
30 
31     public void setId(String id) {
32         this.id = id;
33     }
34 
35     public String getId() {
36         return id;
37     }
38 }
39 
40 /**
41  * 管理學院員工的管理類
42  */
43 class CollegeManager {
44     //返回學院的所有員工
45     public List<CollegeEmployee> getAllEmployee() {
46         List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
47         for (int i = 0; i < 10; i++) {
48             CollegeEmployee emp = new CollegeEmployee();
49             emp.setId("學院員工id= " + i);
50             list.add(emp);
51         }
52         return list;
53     }
54 
55     //輸出學院員工的資訊
56     public void printCollageEmployee() {
57         List<CollegeEmployee> list1 = getAllEmployee();
58         System.out.println("------------學院員工------------");
59         for (CollegeEmployee e : list1) {
60             System.out.println(e.getId());
61         }
62     }
63 
64 }
65 
66 /**
67  * 學校的管理類
68  *  分析:
69  *      直接朋友類:Employee、CollegeManager
70  *      間接朋友類:CollegeEmployee,是一個陌生類,違反了迪米特法則
71  */
72 class SchoolManager {
73     //返回學校總部的員工
74     public List<Employee> getAllEmployee() {
75         List<Employee> list = new ArrayList<Employee>();
76 
77         for (int i = 0; i < 5; i++) {
78             Employee emp = new Employee();
79             emp.setId("學校總部員工id= " + i);
80             list.add(emp);
81         }
82         return list;
83     }
84 
85     //輸出學校總部和學院員工的資訊
86     void printAllEmployee(CollegeManager sub) {
87 
88         //1.將輸出學院的員工的方法,封裝到 CollegeManager 類中
89         sub.printCollageEmployee();
90         //2.輸出學校總部的員工資訊
91         List<Employee> list2 = this.getAllEmployee();
92         System.out.println("------------學校總部員工------------");
93         for (Employee e : list2) {
94             System.out.println(e.getId());
95         }
96     }
97 }

三、小結

  1、迪米特法則的核心是降低類之間的耦合;

  2、但是注意:由於每個類都減少了不必要的依賴,因此迪米特法則只是要求降低類間(物件間)耦合關係,並不是要求完全沒有依賴關係;