六大原則之“迪米特法則(LoD)“筆記

1.迪米特法則:Law of Demeter, LoD),也稱最少知識原則(Least Knowledge Principle, LKP)

定義:Only talk to your immedate friends.(只與直接的朋友通信)。一個對象應該對其他對象有最少的瞭解。(通俗地講,一個類應該對自己需要耦合或調用的類知道得最少)


2.理解:

2.1 只和朋友交流(更準確來講是:直接的朋友)

每個對象都必然會與其他對象有耦合關係,兩個對象之間的耦合就成爲朋友關係,這種關係的類型有很多,如組合、聚合、依賴等。
朋友類的定義:出現在成員變量、方法的輸入輸出參數中的類。   而方法體類內部的類不能算。
2.2 朋友之間也有間距
如果朋友把太多的方法或屬性暴露給你,則過於親密,耦合關係變得異常牢固,而且,修改時涉及的面也就越大,變更引起的風險就越大。因此,要適時反覆衡量:是否可以減少public方法和屬性,改爲private、package-private、protected等訪問權限,及是否可以加上final關鍵字。

3.問題由來:
類與類之間的關係越密切,耦合度越大,當一個類發生改變時,對另一個類的影響也越大。[解決方案]儘量降低類與類之間的耦合。

4.使用LoD的好處:
  1. 降低類與類之間的耦合。

5.難點:
  • LoD法則的核心就是類間解耦,弱耦合,但實現過程則是通過“朋友類”來中轉,結果就是產生了大量的中轉或跳轉類,導致系統的複雜性提高,增加了維護的難度。一個準則:只要跳轉不超過兩次都是可以忍受的,反之則要考慮重構;
  • LoD法則要求解耦,但解耦是有限度的,原則僅供參考,嚴格執行就是“過猶不及”。

6.最佳實踐:

① 在類的劃分上,應該創建有弱耦合的類;
② 在類的結構設計上,每一個類都應當儘量降低成員的訪問權限;
③ 在類的設計上,只要有可能,一個類應當設計成不變類;
④ 在對其他類的引用上,一個對象對其它對象的引用應當降到最低;
⑤ 儘量降低類的訪問權限;
⑥ 謹慎使用序列化功能(類或接口在客戶端變更,卻未在服務端同步更新,引發序列化失敗,,項目管理易疏忽);
⑦ 不要暴露類成員,而應該提供相應的訪問器(屬性)

在實際應用中經常會出現這樣一個方法:放在本類中也可以,放在其他類中也沒有問題,怎麼去衡量呢?建議:如果一個類放在本類中,既不增加類間關係,又不對本類產生不負面影響,就放置在本類中。


7.範例:

7.1  一個常態的編程(肯定是不符LoD的反例)

//體育老老師讓體委清點全班女生個數。類圖如下:


對應源代碼如下:

[java] view plaincopy
  1. public class Teacher {  
  2.     //老師對學生髮布命令,清一下女生  
  3.     public void commond(GroupLeader groupLeader){  
  4.         List<Girl> listGirls = new ArrayList();  
  5.         //初始化女生  
  6.         for(int i=0;i<20;i++){  
  7.             listGirls.add(new Girl());  
  8.         }  
  9.         //告訴體育委員開始執行清查任務  
  10.         groupLeader.countGirls(listGirls);  
  11.     }  
  12. }  
  13.   
  14. public class GroupLeader {  
  15.     //有清查女生的工作  
  16.     public void countGirls(List<Girl> listGirls){  
  17.         System.out.println("女生數量是:"+listGirls.size());  
  18.     }  
  19. }  
  20.   
  21. public class Girl {  
  22. }  
  23.   
  24. public class Client {  
  25.     public static void main(String[] args) {  
  26.         Teacher teacher= new Teacher();  
  27.         //老師發佈命令  
  28.         teacher.commond(new GroupLeader());  
  29.     }  
  30. }  

看看上面的要求:老師 讓 體委  清點  女生 數目。老師與女生是陌生關係啊(老師不需要女生執行任何動作)。顯然,上述做法違背LoD法則。

改如下:


7.2 依據LoD法則解耦(與真實意義上的陌生類解耦,這裏而不應爲上述類圖中未正確體會語義的虛假朋友類Girl):


對應源碼如下:

[java] view plaincopy
  1. public class Teacher {  
  2.     //老師對學生髮布命令,清一下女生  
  3.     public void commond(GroupLeader groupLeader){  
  4.         //告訴體育委員開始執行清查任務  
  5.         groupLeader.countGirls();  
  6.     }  
  7. }  
  8.   
  9. public class GroupLeader {  
  10.     private List<Girl> listGirls;  
  11.     //傳遞全班的女生  
  12.     public GroupLeader(List<Girl> _listGirls){  
  13.         this.listGirls = _listGirls;  
  14.     }  
  15.   
  16.     //有清查女生的工作  
  17.     public void countGirls(){  
  18.         System.out.println("女生數量是:"+listGirls.size());  
  19.     }     
  20. }  
  21.   
  22. public class Girl {  
  23. }  
  24.   
  25. public class Client {  
  26.     public static void main(String[] args) {      
  27.         List<Girl> listGirls = new ArrayList<Girl>();  
  28.         //初始化女生  
  29.         for(int i=0;i<20;i++){  
  30.             listGirls.add(new Girl());  
  31.         }  
  32.       
  33.         Teacher teacher= new Teacher();  
  34.         //老師發佈命令  
  35.         teacher.commond(new GroupLeader(listGirls));  
  36.     }  
  37. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章