1. 程式人生 > >面向對象五大原則-----迪米特法則

面向對象五大原則-----迪米特法則

.get alt str 例子 效率 post bst 分享圖片 pub

  什麽是迪米特法則

  迪米特法則(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.中介者模式

面向對象五大原則-----迪米特法則