五、接口隔離原則
1. 定義
i. 客戶端不應該依賴那些它不需要的接口。
ii. 一旦一個接口太大,則需要將它分割成一些更細小的接口,使用該接口的客戶端僅需知道與之相關的方法即可。
2.分析
i. 接口隔離原則是指使用多個專門的接口,而不使用單一的總接口。每一個接口應該承擔一種相對獨立的角色,不多不少,不幹不該乾的事,該乾的事都要幹。
ii. 使用接口隔離原則拆分接口時,首先必須滿足單一職責原則,將一組相關的操作定義在一個接口中,且在滿足高內聚的前提下,接口中的方法越少越好。
iii. 可以在進行系統設計時採用定製服務的方式,即爲不同的客戶端提供寬窄不同的接口,只提供用戶需要的行爲,而隱藏用戶不需要的行爲
3.實例
i. 下圖展示了一個擁有多個客戶類的系統,在系統中定義了一個巨大的接口(胖接口)AbstractService來服務所有的客戶類。如圖所示:
圖(一)
圖(二)
圖(一)和圖(二)分析:
圖(一)爲什麼到圖(二)哪?因爲這樣做既滿足了接口隔離原則,又滿足了單一原則,何樂而不爲呢,但是也帶來了很多的不便,類增多了。
總結:類應該完全依賴相應的專門的接口
六、合成複用原則
1.定義
i. 儘量使用對象組合,而不是繼承來達到複用的目的。
2.分析
i. 合成複用原則就是指在一個新的對象裏通過關聯關係(包括組合關係和聚合關係)來使用一些已有的對象,使之成爲新對象的一部分;新對象通過委派調用已有對象的方法達到複用其已有功能的目的。簡言之:要儘量使用組合/聚合關係,少用繼承。
ii. 在面向對象設計中,可以通過兩種基本方法在不同的環境中複用已有的設計和實現,即通過組合/聚合關係或通過繼承。
a) 繼承複用:實現簡單,易於擴展。破壞系統的封裝性;從基類繼承而來的實現是靜態的,不可能在運行時發生改變,沒有足夠的靈活性;只能在有限的環境中使用。(“白箱”複用 )
b) 組合/聚合複用:耦合度相對較低,選擇性地調用成員對象的操作;可以在運行時動態進行。(“黑箱”複用 )
iii. 組合/聚合可以使系統更加靈活,類與類之間的耦合度降低,一個類的變化對其他類造成的影響相對較少,因此一般首選使用組合/聚合來實現複用;其次才考慮繼承,在使用繼承時,需要嚴格遵循里氏代換原則,有效使用繼承會有助於對問題的理解,降低複雜度,而濫用繼承反而會增加系統構建和維護的難度以及系統的複雜度,因此需要慎重使用繼承複用。
3. 實例
i. 某教學管理系統部分數據庫訪問類設計如圖所示:
圖(一)
圖(二)
圖(一)和圖(二)分析:
圖(一)爲什麼到圖(二)哪?因爲如果需要更換數據庫連接方式,如原來採用JDBC連接數據庫,現在採用數據庫連接池連接,則需要修改DBUtil類源代碼。如果StudentDAO採用JDBC連接,但是TeacherDAO採用連接池連接,則需要增加一個新的DBUtil類,並修改StudentDAO或TeacherDAO的源代碼,使之繼承新的數據庫連接類,這將違背開閉原則,系統擴展性較差。
總結:類中應用,儘量使用對象組合而不是用繼承來達到複用的目的。
七、迪米特法則
1. 定義
i. 每一個軟件單位對其他的單位都只有最少的知識,而且侷限於那些與本單位密切相關的軟件單位。
2. 分析
i.迪米特法則就是指一個軟件實體應當儘可能少的與其他實體發生相互作用。這樣,當一個模塊修改時,就會盡量少的影響其他的模塊,擴展會相對容易,這是對軟件實體之間通信的限制,它要求限制軟件實體之間通信的寬度和深度。
ii. 狹義的迪米特法則:可以降低類之間的耦合,但是會在系統中增加大量的小方法並散落在系統的各個角落,它可以使一個系統的局部設計簡化,因爲每一個局部都不會和遠距離的對象有直接的關聯,但是也會造成系統的不同模塊之間的通信效率降低,使得系統的不同模塊之間不容易協調。
iii. 廣義的迪米特法則:指對對象之間的信息流量、流向以及信息的影響的控制,主要是對信息隱藏的控制。信息的隱藏可以使各個子系統之間脫耦,從而允許它們獨立地被開發、優化、使用和修改,同時可以促進軟件的複用,由於每一個模塊都不依賴於其他模塊而存在,因此每一個模塊都可以獨立地在其他的地方使用。一個系統的規模越大,信息的隱藏就越重要,而信息隱藏的重要性也就越明顯。
iv. 迪米特法則的主要用途在於控制信息的過載。
1.在類的劃分上,應當儘量創建松耦合的類,類之間的耦合度越低,就越有利於複用,一個處在松耦合中的類一旦被修改,不會對關聯的類造成太大波及
2.在類的結構設計上,每一個類都應當儘量降低其成員變量和成員函數的訪問權限
3.在類的設計上,只要有可能,一個類型應當設計成不變類
4.在對其他類的引用上,一個對象對其他對象的引用應當降到最低。
3. 實例
i.某系統界面類(如Form1、Form2等類)與數據訪問類(如DAO1、DAO2等類)之間的調用關係較爲複雜。如圖所示:
圖(一)
圖(二)
圖(一)和圖(二)分析:
圖(一)爲什麼到圖(二)哪?因爲這樣就可以降低類的耦合性,是類中功能更加單一,相當於外觀模式。
總結:一個軟件實體應當儘可能少的與其他實體發生相互作用