迪米特法則:迪米特法則又叫最小知識原則,也就是說:一個對象應當對其他對象盡可能少的了解,不和陌生人說話。
狹義的迪米特法則是指: 如果兩個類不必要直接通訊,這兩個類就不必要發生直接的關系,那麼當一個類需要調用另一個類中的方法時,可以通過第三者轉發這個調用。
廣義的迪米特法則是指:一個模塊設計的好壞的一個重要的標志在於將該模塊的內部數據和實現部分影藏起來。
在運用迪米特法則到系統的設計中時,要注意以下幾點:
第一:在類的劃分上,應當創建弱耦合的類,類與類之間的耦合越弱,就越有利於實現可復用的目標。
第二:在類的結構設計上,每個類都應該降低成員的訪問權限。
第三:在類的設計上,只要有可能,一個類應當設計成不變的類。
第四:在對其他類的應用上,一個對象對其他類的對象的應用應該降到最低。
第五:盡量限制局部變量的有效范圍。
但是過度使用迪米特法則,也會造成系統的不同模塊之間的通信效率降低,使系統的不同模塊之間不容易協調等缺點。同時,因為迪米特法則要求類與類之間盡量不直接通信,如果類之間需要通信就通過第三方轉發的方式,這就直接導致了系統中存在大量的中介類,這些類存在的唯一原因是為了傳遞類與類之間的相互調用關系,這就毫無疑問的增加了系統的復雜度。解決這個問題的方式是:使用依賴倒轉原則(通俗的講就是要針對接口編程,不要針對具體編程),這要就可以是調用方和被調用方之間有了一個抽象層,被調用方在遵循抽象層的前提下就可以自由的變化,此時抽象層成了調用方的朋友。
故事分析:
慈禧太後要召見龐青龍。龐青龍在見到慈禧太後前經歷了那些過程呢?首先,當然是有人通知龐青龍要被召見,通知龐青龍的人當然不會是慈禧本人!慈禧只是下達旨意,然後又相關的只能部門傳達旨意,相關部門的領導人也不會親自去通知龐青龍,這些領導人會派遣信得過的人去,而這個被派遣的人也不是說想見龐青龍就能見得了的,他也必須通過和龐青龍熟悉的人,最後才能見到龐青龍,從而才能成功的傳達旨意;第二:在進宮前,龐青龍必須卸掉自己隨身攜帶的任何武器;第三:會有專門的只能部門對龐青龍進行全身徹底的檢查,以防有任何可以傷害人的東西攜帶在身上,當然這個過程可能非常的復雜和繁瑣。最後,由一個太監帶路到慈禧面前。當然,見到慈禧的時候,龐青龍不是和慈禧坐在一起的,要報仇距離!慈禧也深深的懂得保持距離的重要性!
見到慈禧太後以後慈禧也沒有和龐青龍直接說話,因為慈禧不和陌生人說話!而是同時身邊的人傳達自己的話,慈禧只需頤指氣使即可。
從上面的過程中我們可以看出處處體現了迪米特法則的應用,慈禧知道龐青龍這個人肯定是通過一層又一層的關系得知的,就是迪米特法則中的第三者轉發而且這裡面說不定還有若干個第三者的轉發!而從慈溪下旨召見龐青龍到龐青龍收到旨意,這中間又是完美的提現了迪米特法則,這中間經歷無數的第三者!就連龐青龍面見到慈禧後,慈禧也不和他直接說話,而是通過身邊的人傳話,這慈禧是不是太傻了,直接和他說不就行了嗎?慈禧當然不傻,因為她深知迪米特法則的重要。兩個類的對象之間如果不發生直接的聯系就不直接發生關系!
不過這也產生了一個問題,這中間經歷這麼多的轉發,需要機構和人啊?或許這就是為什麼當時的清政府機構那麼龐大、財政開支驚人的原因之一吧^_^
Java代碼實現:
新建一個陌生人的抽象父類,其他的陌生人繼承這個接口:
package com.diermeng.designPattern.LoD;
/*
* 抽象的陌生人類
*/
public abstract class Stranger {
/*
* 抽象的行為方法
*/
public abstract void operation();
}
龐青龍實現繼承實現陌生人抽象類:
package com.diermeng.designPattern.LoD.impl;
import com.diermeng.designPattern.LoD.Stranger;
/*
* 龐青龍對抽象類Stranger的實現
*/
public class PangQingyong extends Stranger{
/*
* 操作方法
* @see com.diermeng.designPattern.LoD.Stranger#operation()
*/
public void operation(){
System.out.println("禀報太後:我是龐青龍,我擅長用兵打仗!");
}
}
朋友類,這裡指太監類
package com.diermeng.designPattern.LoD.impl;
import com.diermeng.designPattern.LoD.Stranger;
/*
* 太監類
*/
public class Taijian {
/*
* 太監類的操作方法
*/
public void operation(){
System.out.println("friends paly");
}
/*
* 由太監類提供Cixi需要的方法
*/
public void findStranger() {
//創建一個Stranger
Stranger stranger = new PangQingyong();
//執行相應的方法
stranger.operation();
}
}
調用者類的代碼,在這裡是慈禧太後類:
package com.diermeng.designPattern.LoD.impl;
/*
* 慈禧類
*/
public class Cixi {
//擁有對太監的引用,即對“朋友”的引用
private Taijian taijian;
//得到一個太監對象
public Taijian getTaijian() {
return taijian;
}
//設置一個太監對象
public void setTaijian(Taijian taijian) {
this.taijian = taijian;
}
//操作方法
public void operation(){
System.out.println("someone play");
}
}
建立一個測試類,代碼如下:
package com.diermeng.designPattern.LoD.client;
import com.diermeng.designPattern.LoD.impl.Taijian;
import com.diermeng.designPattern.LoD.impl.Cixi;
/*
* 測試客戶端
*/
public class LoDTest {
public static void main(String[] args) {
//聲明並實例化慈禧類
Cixi zhangsan = new Cixi();
//設置一個太監實例化對象,即找到一個“朋友”幫忙做事
zhangsan.setTaijian(new Taijian());
//慈禧通過宮中太監傳話給陌生人
zhangsan.getTaijian().findStranger();
}
}
程序運行結果如下:
禀報太後:我是龐青龍,我擅長用兵打仗!
已有應用簡介:
迪米特法則或者最少知識原則作為面向對象設計風格的一種法則,也是很多著名軟件設計系統的指導原則,比如火星登陸軟件系統、木星的歐羅巴衛星軌道飛船軟件系統。
溫馨提示:
迪米特法則是一種面向對象系統設計風格的一種法則,尤其適合做大型復雜系統設計指導原則。但是也會造成系統的不同模塊之間的通信效率降低,使系統的不同模塊之間不容易協調等缺點。同時,因為迪米特法則要求類與類之間盡量不直接通信,如果類之間需要通信就通過第三方轉發的方式,這就直接導致了系統中存在大量的中介類,這些類存在的唯一原因是為了傳遞類與類之間的相互調用關系,這就毫無疑問的增加了系統的復雜度。解決這個問題的方式是:使用依賴倒轉原則(通俗的講就是要針對接口編程,不要針對具體編程),這要就可以是調用方和被調用方之間有了一個抽象層,被調用方在遵循抽象層的前提下就可以自由的變化,此時抽象層成了調用方的朋友