學習設計模式 - 六大基本原則之迪米特法則
設計模式總共有六大基本原則,統稱為SOLID (穩定)原則,分別是S-單一職責原則(Single Responsibility Principle), O-開閉原則(Open closed Principle),L-裏氏替換原則(Liskov Substitution Principle),L-迪米特法則(Law of Demeter),I-接口隔離原則(Interface Segregation Principle),D-依賴倒置原則(Dependence Invension Principle)。
L-迪米特法則(Law of Demeter)
一、定義
1) Each unit should have only limited knowledge about other units: only units "closely" related to the current unit. (一個類應該對自己需要耦合或調用的類知道的最少)
2) Each unit should only talk to its friends; don‘t talk to strangers.
3) Only talk to your immediate friends. (只和直接的朋友通信)
來源:https://en.wikipedia.org/wiki/Law_of_Demeter
二、理解
迪米特法則,也稱最少知識原則。一個類應該對自己需要耦合或調用的類知道的最少。通俗地來講,就是一個類只關心自己調用類提供的方法(通常是public方法),對其他類的內部實現概不關心。
1) 從調用者的角度考慮,應只和直接的朋友交流。
什麽是直接的朋友?即是,內部成員屬性、方法的輸入輸出參數。方法內部的類不算是朋友類。以下代碼中GroupLeader是Teacher的直接朋友類,方法內部的List<Girl>不是朋友類。也就是與一個陌生的Girl類交流,這樣就破壞了Teacher類的健壯性。
1 public class Teacher { 2 //老師對學生發布命令,清一下女生 3 public void commond(GroupLeader groupLeader){ 4 List 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 }
修改代碼如下:
public class Teacher { //老師對學生發布命令,清一下女生 public void commond(GroupLeader groupLeader){ //告訴體育委員開始執行清查任務 groupLeader.countGirls(); } }
修改後的groupleader類 :
public class GroupLeader { private List<Girl> listGirls; //傳遞全班的女生進來 public GroupLeader(List<Girl> _listGirls){ this.listGirls = _listGirls; } //清查女生數量 public void countGirls(){ System.out.println("女生數量是:"+this.listGirls.size()); } }
修改後的場景類:
public class Client { public static void main(String[] args) { //產生一個女生群體 List<Girl> listGirls = new ArrayList<Girl>(); //初始化女生 for(int i=0;i<20;i++){ listGirls.add(new Girl()); } Teacher teacher= new Teacher(); //老師發布命令 teacher.commond(new GroupLeader(listGirls)); } }
總結,把Teacher類中的List<girl>的初始化,移動到場景類,並在GroupLeader中增加了對Girl的註入,避開了Teacher類對陌生類的訪問,降低了系統的耦合性,提高了系統的健壯性。
2) 從被調用者的角度考慮,應對外暴露最少的屬性或方法,暴露的方法越多,耦合性越強。
是自己的,就是自己的。如果一個方法,放在本類中,既不增加類間關系,也不會對本類產生負面影響,就放在本類中
迪米特法則要求類“羞澀”一點,盡量不要對外公布太多的public方法和非靜態的public變量,盡量內斂,多使用private、package-private、protected等訪問權限。
三、註意事項
迪米特法則要求類間解耦,但解耦是有限度的。類間解耦,弱耦合了,類的復用率才會高,其要求的結果是產生大量的中間類、跳轉類,這樣會增加系統的復雜度,同時也會給維護帶來難度。所以,需要在兩者之前反復權衡,既做到結構清晰,又做到低耦合高內聚。
在實際應用中,如果一個類跳轉兩次以上才能訪問到另一個類,就需要想辦法進行重構了,為什麽是兩次以上呢?因為一個系統的成功不僅僅是一個標準或是原則就能夠決定的,有非常多的外在因素決定,跳轉次數越多,系統越復雜,維護就越困難,所以只要跳轉不超過兩次都是可以忍受的,這需要具體問題具體分析。
學習資料:
《設計模式之禪》秦小波 著
白話設計——淺談迪米特法則
學習設計模式 - 六大基本原則之迪米特法則