1.迪米特法則:Law of Demeter, LoD),也稱最少知識原則(Least Knowledge Principle, LKP)
定義:Only talk to your immedate friends.(只與直接的朋友通信)。一個對象應該對其他對象有最少的瞭解。(通俗地講,一個類應該對自己需要耦合或調用的類知道得最少)
2.理解:
2.1 只和朋友交流(更準確來講是:直接的朋友)
- 降低類與類之間的耦合。
- LoD法則的核心就是類間解耦,弱耦合,但實現過程則是通過“朋友類”來中轉,結果就是產生了大量的中轉或跳轉類,導致系統的複雜性提高,增加了維護的難度。一個準則:只要跳轉不超過兩次都是可以忍受的,反之則要考慮重構;
- LoD法則要求解耦,但解耦是有限度的,原則僅供參考,嚴格執行就是“過猶不及”。
① 在類的劃分上,應該創建有弱耦合的類;
② 在類的結構設計上,每一個類都應當儘量降低成員的訪問權限;
③ 在類的設計上,只要有可能,一個類應當設計成不變類;
④ 在對其他類的引用上,一個對象對其它對象的引用應當降到最低;
⑤ 儘量降低類的訪問權限;
⑥ 謹慎使用序列化功能(類或接口在客戶端變更,卻未在服務端同步更新,引發序列化失敗,,項目管理易疏忽);
⑦ 不要暴露類成員,而應該提供相應的訪問器(屬性)。
7.1 一個常態的編程(肯定是不符LoD的反例)
//體育老老師讓體委清點全班女生個數。類圖如下:
對應源代碼如下:
- public class Teacher {
- //老師對學生髮布命令,清一下女生
- public void commond(GroupLeader groupLeader){
- List<Girl> listGirls = new ArrayList();
- //初始化女生
- for(int i=0;i<20;i++){
- listGirls.add(new Girl());
- }
- //告訴體育委員開始執行清查任務
- groupLeader.countGirls(listGirls);
- }
- }
- public class GroupLeader {
- //有清查女生的工作
- public void countGirls(List<Girl> listGirls){
- System.out.println("女生數量是:"+listGirls.size());
- }
- }
- public class Girl {
- }
- public class Client {
- public static void main(String[] args) {
- Teacher teacher= new Teacher();
- //老師發佈命令
- teacher.commond(new GroupLeader());
- }
- }
看看上面的要求:老師 讓 體委 清點 女生 數目。老師與女生是陌生關係啊(老師不需要女生執行任何動作)。顯然,上述做法違背LoD法則。
改如下:
7.2 依據LoD法則解耦(與真實意義上的陌生類解耦,這裏而不應爲上述類圖中未正確體會語義的虛假朋友類Girl):
對應源碼如下:
- public class Teacher {
- //老師對學生髮布命令,清一下女生
- public void commond(GroupLeader groupLeader){
- //告訴體育委員開始執行清查任務
- groupLeader.countGirls();
- }
- }
- public class GroupLeader {
- private List<Girl> listGirls;
- //傳遞全班的女生
- public GroupLeader(List<Girl> _listGirls){
- this.listGirls = _listGirls;
- }
- //有清查女生的工作
- public void countGirls(){
- System.out.println("女生數量是:"+listGirls.size());
- }
- }
- public class Girl {
- }
- 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));
- }
- }