面向對象五大原則-----迪米特法則
什麽是迪米特法則
迪米特法則(Law of Demeter )又叫做最少知識原則,也就是說,一個對象應當對其他對象盡可能少的了解。不和陌生人說話。英文簡寫為: LoD。
迪米特法則最初是用來作為面向對象的系統設計風格的一種法則,於1987年秋天由lan holland在美國東北大學為一個叫做迪米特的項目設計提出的。
迪米特法則的模式與意義
迪米特法則可以簡單說成:talk only to your immediate friends。 對於OOD來說,又被解釋為下面幾種方式:一個軟件實體應當盡可能少的與其他實體發生相互作用。每一個軟件單位對其他的單位都只有最少的知識,而且局限於那些與本單位密切相關的軟件單位。
迪米特法則的初衷在於降低類之間的耦合。由於每個類盡量減少對其他類的依賴,因此,很容易使得系統的功能模塊功能獨立,相互之間不存在(或很少有)依賴關系。
迪米特法則不希望類之間建立直接的聯系。如果真的有需要建立聯系,也希望能通過它的友元類來轉達。因此,應用迪米特法則有可能造成的一個後果就是:系統中存在大量的中介類,這些類之所以存在完全是為了傳遞類之間的相互調用關系——這在一定程度上增
加了系統的復雜度。
狹義的迪米特法則
如果兩個類不必彼此直接通信,那麽這兩個類就不應當發生直接的相互作用。如果其中一個類需要調用另一類的某一個方法的話,可以通過第三者轉發這個調用。
這麽看不太形象,我們來舉個例子,和陌生人說話,甲和朋友認識,朋友和陌生人認識,而甲和陌生人不認識,這時甲可以直接和朋友說話,朋友可以直接和陌生人說話,而如果甲想和陌生人說話,就必須通過朋友
首先,第一種方式代碼實現:
1 public class Jia{ 2 public void play(Friend friend){ 3 friend.play(); 4 } 5 6 public void play(Stranger stranger) { 7 stranger.play(); 8 } 9 }
1 //朋友 2 public class Friend { 3 public void play(){ 4 System.out.println("朋友"); 5 }6 }
1 //陌生人 2 public class Stranger { 3 public void play(){ 4 System.out.println("陌生人"); 5 } 6 }
這種方式是肯定不對的,甲根本沒有通過朋友,直接引用了陌生人的方法,不符合迪米特法則
第二種方式
代碼實現
1 //甲 2 public class Jia{ 3 public void play(Friend friend){ 4 friend.play(); 5 Stranger stranger = friend.getStranger(); 6 stranger.play(); 7 } 8 }
1 //朋友 2 public class Friend { 3 public void play(){ 4 System.out.println(朋友"); 5 } 6 7 public Stranger getStranger() { 8 return new Stranger(); 9 } 10 }
1 //陌生人 2 public class Stranger { 3 public void play(){ 4 System.out.println("陌生人"); 5 } 6 }
這樣的方式呢,看上去陌生人的實例是通過朋友來創建了,但還是不行,因為甲中包含的陌生人的引用,甲還是和陌生人直接關聯上了,所以,不符合迪米特法則,我們要的是甲和陌生人沒有一丁點直接關系
第三種方式
1 //甲 2 public class Jia{ 3 private Friend friend; 4 5 public Friend getFriend() { 6 return friend; 7 } 8 9 public void setFriend(Friend friend) { 10 this.friend = friend; 11 } 12 13 public void play(Friend friend){ 14 friend.play(); 15 } 16 }
1 //朋友 2 public class Friend { 3 public void play(){ 4 System.out.println("朋友"); 5 } 6 7 public void playWithStranger() { 8 Stranger stranger = new Stranger(); 9 stranger.play(); 10 } 11 }
1 public class Stranger { 2 public void play(){ 3 System.out.println("陌生人"); 4 } 5 }
這種方式,甲和陌生人之間就沒有了任何直接聯系,這樣就避免了甲和陌生人的耦合度過高
當然還有一種更好的方式,與依賴倒轉原則結合,為陌生人創建一個接口
1 //甲 2 public class Jia{ 3 private Friend friend; 4 private Stranger stranger; 5 6 public Stranger getStranger() { 7 return stranger; 8 } 9 10 public void setStranger(Stranger stranger) { 11 this.stranger = stranger; 12 } 13 14 public Friend getFriend() { 15 return friend; 16 } 17 18 public void setFriend(Friend friend) { 19 this.friend = friend; 20 } 21 22 public void play() { 23 System.out.println("someone play"); 24 friend.play(); 25 stranger.play(); 26 } 27 }
1 public class Friend { 2 public void play(){ 3 System.out.println("朋友"); 4 } 5 }
1 //陌生人抽象類 2 public abstract class Stranger { 3 public abstract void play(); 4 }
1 //具體陌生人 2 public class StrangerA extends Stranger { 3 4 public void play() { 5 System.out.println("陌生人"); 6 } 7 8 }
這樣的方式,和甲直接通信的是陌生人的抽象父類,和具體陌生人沒有直接關系,所以符合迪米特法則
狹義的迪米特法則的缺點:
1、在系統裏造出大量的小方法,這些方法僅僅是傳遞間接的調用,與系統的商務邏輯無關。
2、遵循類之間的迪米特法則會是一個系統的局部設計簡化,因為每一個局部都不會和遠距離的對象有直接的關聯。但是,這也會造成系統的不同模塊之間的通信效率降低,也會使系統的不同模塊之間不容易協調。
迪米特法則應用實例
1.外觀模式
2.中介者模式
面向對象五大原則-----迪米特法則