設計原則之【迪米特法則】


設計原則是指導我們代碼設計的一些經驗總結,也就是“心法”;面向對象就是我們的“武器”;設計模式就是“招式”。

以心法為基礎,以武器運用招式應對復雜的編程問題。

來吧,通過生活中一個小場景,一起系統學習這6大設計原則。

SOLID原則--SRP單一職責原則

SOLID原則--OCP開放封閉原則

SOLID法則--LSP里式替換原則

SOLID原則--ISP接口隔離原則

SOLID原則--DIP依賴反轉原則

LOD迪米特法則

實習生表妹第一天去公司...

我:妹啊,第一天去公司感覺怎么樣呢?

表妹:感覺同事們有些冷淡😔

我:咋啦?

表妹:我在辦理入職的時候,和我對接的張同事突然有事走開了,我當時看另一位同事在聊微信,就麻煩他幫我辦理,但是他卻讓我等張同事回來。

我:原來是這樣子,首先,他不是你的直接對接人呀,其次,說不定他自己也有事情在處理呢。

這不很像我們軟件開發中的“迪米特法則”嘛?


每個模塊只應該了解那些與它關系密切的模塊的有限知識。或者說,每個模塊只和自己的朋友“說話”,不和陌生人“說話”。也叫“最少知識原則”。

從上面的描述中,我們可以看出,迪米特法則包含前后兩個部分,如果我們把一個模塊看作是一個人,那么要實現“一個人應該對其他人有最少的了解”,應該做到這兩點:

1、只和直接的朋友交流;

2、減少對朋友的了解。

接下來就詳細說說如何做到這兩點。

首先,我們來看一下,什么叫“朋友”?

軟件開發中的朋友:兩個對象之間的耦合關系稱之為“朋友”,通常有依賴、關聯、聚合和組合等。而直接朋友則通常表現為關聯、聚合和組合關系,即兩個對象之間聯系更為緊密,通常以成員變量,方法的參數和返回值的形式出現。

減少對朋友的了解

一個類公開的public屬性或方法越多,修改時涉及的面也就越大,變更引起的風險擴散就越大。

就如同前面的場景,表妹只知道自己的直接對接人是負責給新員工辦理入職手續的,但是具體的操作,表妹是不知道的。

我們來看一下明星和粉絲互動的場景:

 1 // 粉絲類
 2 public class Fans {
 3  4     public void shakeHands(){
 5         System.out.println("與偶像握手");
 6     }
 7     public void sign(){
 8         System.out.println("偶像給我簽名");
 9     }
10     public void groupPhoto(){
11         System.out.println("與偶像合影");
12     }
13     
14     public void interaction(){
15         shakeHands();
16         sign();
17         groupPhoto();
18     }
19 }
20 21 // 偶像類
22 public class Star{
23     private Fans f;
24     
25     ...
26     
27     public void interactWithFans(){
28       // 現在偶像要和粉絲互動,正常來說,她只需要調用interaction()方法即可,
29       // 但是,她發現Fans所有的方法都是公開的,該如何互動呢?可能:
30         f.shakeHands();
31         f.sign();
32         f.groupPhoto();
33         
34         // 亦或是以下的操作 
35         f.sign();
36         f.groupPhoto();
37         
38         // 還可能是以下的操作
39         f.interaction();
40     }
41 }

你看,粉絲作為明星的朋友,公開了很多種互動方式,使得明星對粉絲的了解過多,這樣明星得花很大精力去考慮以哪種方式和粉絲互動。那么,這里的f對象應該暴露哪些方法呢?很顯然,對於明星Star來說,只需關注和粉絲的互動操作,而不關心具體是如何互動的,因此,只需要暴露interaction()方法。

那么,上述的代碼應該修改為:

 1 // 粉絲類
 2 public class Fans {
 3  4     private void shakeHands(){
 5         System.out.println("與偶像握手");
 6     }
 7     private void sign(){
 8         System.out.println("偶像給我簽名");
 9     }
10     private void groupPhoto(){
11         System.out.println("與偶像合影");
12     }
13     
14     public void interaction(){
15         shakeHands();
16         sign();
17         groupPhoto();
18     }
19 }
20 21 // 偶像類
22 public class Star{
23     private Fans f;
24     
25     ...
26     
27     public void interactWithFans(){
28         // 這時候,偶像她只管與粉絲互動就可以了,不管具體是握手、簽名還是合影。
29         f.interaction();
30     }
31 }

你看,這時明星和粉絲的互動就簡單多了。

通俗地講,一個類應該對自己需要耦合或調用的類知道得最少,我就知道你提供的這么多public方法,我就調用這么多,其他的我一概不關心。

其實,明星由於全身心投入藝術,所以許多日常事務由經濟人負責處理,如粉絲見面會,和媒體公司的業務洽談等。這里的經紀人就是明星的直接朋友,粉絲和媒體公司是明星的間接朋友。

只和直接的朋友交流

現在,我們在剛才的場景中,加多一個經紀人類:

 1 // 粉絲類
 2 public class Fans {
 3  4     private void shakeHands(){
 5         System.out.println("與偶像握手");
 6     }
 7     private void sign(){
 8         System.out.println("偶像給我簽名");
 9     }
10     private void groupPhoto(){
11         System.out.println("與偶像合影");
12     }
13     
14     public void interaction(){
15         shakeHands();
16         sign();
17         groupPhoto();
18     }
19 }
20 21 // 經紀人類
22 public class Broker {
23     private Fans f;       // 負責粉絲見面會
24     private Company c;    // 負責商務洽談
25     ...
26     
27     // 開粉絲互動會
28     public void openInteraction() {
29         f.interaction();
30     }
31 }
32 33 // 偶像類
34 public class Star{
35     // 明星的經紀人
36     private Broker b;
37     
38     ...
39     
40     // 粉絲互動會,由經紀人打理
41     public void interactWithFans(){
42         b.openInteraction();
43     }
44 }

你看,明星的直接朋友只有一個,也就是他的經紀人,無需了解粉絲和公司。這樣做有一個好處,就是能夠簡化對象與對象之間的通信,進而減輕依賴,提供更高的靈活性,當然也可以提供一定的安全性。

總結

不該有直接依賴關系的類之間,不要有依賴;

有依賴關系的類之間,盡量只依賴必要的接口(也就是定義中的“有限知識”)。

好啦,不要為了應用設計原則而應用設計原則,我們在應用設計原則的時候,一定要具體問題具體分析。

參考

《大話設計模式》

《設計模式之禪》

https://www.jianshu.com/p/14589fb6978e

https://www.itheima.com/news/20210819/173818.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM