1. 程式人生 > >設計模式的七大原則(6) --迪米特法則

設計模式的七大原則(6) --迪米特法則

# 前言 迪米特法則,聽名字有點奇怪,但是這個法則真的非常非常有意思,在我看來,這個法則其實描述的就是一個矜持的小姑娘,害羞的惹人憐愛。但是啊,姑娘雖好,切不可"貪杯"哦~ # 基本介紹 1. 一個物件應該對其他物件保持最少的瞭解。 2. 類與類關係越密切,耦合度越大 3. 一個類對自己依賴的類知道的越少越好。也就是說,對於被依賴的類不管多麼複雜,都儘量將邏輯封裝在類的內部。對外除了提供的public 方法,不對外洩露任何資訊 4. 迪米特法則還有個更簡單的定義:只與直接(熟悉)的朋友通訊 5. 直接(熟悉)的朋友:每個物件都會與其他物件有耦合關係,只要兩個物件之間有耦合關係, 我們就說這兩個物件之間是朋友關係。耦合的方式很多,依賴,關聯,組合,聚合等。 其中,我們稱出現成員變數,方法引數,方法返回值中的類為直接的朋友,而出現在區域性變數中的類不是直接的朋友。也就是說,陌生的類最好不要以區域性變數 的形式出現在類的內部。 --- 把上面的概念一一翻譯成人話就是: 1. 我們這個類姑娘啊,因為太矜持了不善於社交,所以對其他類夥伴們不怎麼熟悉。 2. 類姑娘實在是太害羞了,一旦與別人多說幾句話就會緊張的不知所措,頻頻犯錯。 3. 矜持的類姑娘儘管心思很活躍,愛多想。但是給別人的感覺都是純潔的像一張白紙。 4. 因為類姑娘太過於矜持,害怕陌生人,認為陌生人都是壞人,所以只與自己熟悉的朋友交流。 5. 類姑娘熟悉的朋友有:成員變數,方法引數,方法返回值的物件。而出現在其他地方的類都是陌生人,壞人!本姑娘拒絕與你交流!!! 哈哈,這樣應該大家都能理解了。總而言之就一句話:**一個類應該儘量不要知道其他類太多的東西,不要和陌生的類有太多接觸**。 # 案例 ``` //總公司員工 class Employee{ private String id; public void setId(String id){ this.id = id; } public String getId(){ return id; } } //分公司員工 class SubEmployee{ private String id; public void setId(String id){ this.id = id; } public String getId(){ return id; } } class SubCompanyManager{ public List getAllEmployee(){ List list = new ArrayList(); for(int i=0; i<100; i++){ SubEmployee emp = new SubEmployee(); //為分公司人員按順序分配一個ID emp.setId("分公司"+i); list.add(emp); } return list; } } class CompanyManager{ public List getAllEmployee(){ List list = new ArrayList(); for(int i=0; i<30; i++){ Employee emp = new Employee(); //為總公司人員按順序分配一個ID emp.setId("總公司"+i); list.add(emp); } return list; } public void printAllEmployee(SubCompanyManager sub){ List list1 = sub.getAllEmployee(); for(SubEmployee e:list1){ System.out.println(e.getId()); } List list2 = this.getAllEmployee(); for(Employee e:list2){ System.out.println(e.getId()); } } } public class Client{ public static void main(String[] args){ CompanyManager e = new CompanyManager(); e.printAllEmployee(new SubCompanyManager()); } } ``` 現在這個設計的主要問題出在CompanyManager中,根據迪米特法則,只與直接的朋友發生通訊,而SubEmployee類並不是CompanyManager類的直接朋友(以區域性變量出現的耦合不屬於直接朋友),從邏輯上講總公司只與他的分公司耦合就行了,與分公司的員工並沒有任何聯絡,這樣設計顯然是增加了不必要的耦合。按照迪米特法則,應該避免類中出現這樣非直接朋友關係的耦合。修改後的程式碼如下: ``` class SubCompanyManager{ public List getAllEmployee(){ List list = new ArrayList(); for(int i=0; i<100; i++){ SubEmployee emp = new SubEmployee(); //為分公司人員按順序分配一個ID emp.setId("分公司"+i); list.add(emp); } return list; } public void printEmployee(){ List list = this.getAllEmployee(); for(SubEmployee e:list){ System.out.println(e.getId()); } } } class CompanyManager{ public List getAllEmployee(){ List list = new ArrayList(); for(int i=0; i<30; i++){ Employee emp = new Employee(); //為總公司人員按順序分配一個ID emp.setId("總公司"+i); list.add(emp); } return list; } public void printAllEmployee(SubCompanyManager sub){ sub.printEmployee(); List list2 = this.getAllEmployee(); for(Employee e:list2){ System.out.println(e.getId()); } } } ``` 修改後,為分公司增加了列印人員ID的方法,總公司直接呼叫來列印,從而避免了與分公司的員工發生耦合。 # 總結 雖然說矜持害羞的姑娘惹人憐愛,但是我相信在座的各位碼狼們一定會特別的苦惱,因為很多簡單的事卻變得不那麼簡單直接。在你發起進攻的時候往往會給你當頭一棒。 所以啊,如果我們要遵循迪米特法則,也要根據我們的業務場景合理設計,反覆權衡,既做到結構清晰,又要高內聚低耦合。不要過分的迷戀這個矜持的小姑娘,否則簡單直接的事也會變得非常的