使用設計模式的目的是為讓我們所寫的程序低耦合、高內聚,可維護性好,可擴展性高,高重用、高靈活。
設計模式的原則就是設計模式為什麼這樣設計的依據。
設計模式分為三種類型:
一個類應該隻負責一項職責。
若類A有兩個職責:職責1和職責2。當職責1需求更變時,會去改變類A,有可能造成職責2的功能錯誤。所以需要將類A拆分成類A1和類A2。
一項職責並不代表一個類隻有一個方法,比如UserMapper隻來負責對user表的增刪改查。
通常情況下,我們應該遵守單一職責原則,隻有邏輯足夠簡單或者類中方法數量足夠小時,可以在代碼中違反,比如可以在方法級別保持單一職責而在類級別違反。
客戶端不應該依賴它不需要的接口,即一個類對另一個類的依賴應該建立在最小的接口上。
拿下圖舉例來說,類B、D實現瞭接口I,然後類A通過接口I來使用類B中的方法,但是類A隻會使用接口中的1、2、3三個方法,但是B卻要實現接口中的全部方法。那麼接口I對於類A來說就不是最小接口,類B需要實現不需要的方法。
按照接口隔離原則,應當將接口I拆分成多個獨立的接口,創建類A需要的方法的接口。
97afae7e4c126384e391378c4f9af682
1)高層模塊不應該依賴底層模塊,二者都應該依賴其抽象;
2)抽象不應該依賴細節,細節應該依賴抽象;
3)中心思想:面向接口編程;變量的聲明類型盡量是抽象類或接口,這樣我們的變量引用和實際對象間就存在一個緩沖層,利於程序擴展和優化。
舉例說明:
我們要編寫Person類實現接受消息的功能。
不符合依賴倒轉方式:
ad39ad759511d4f275bc610507a6c879
優化:
依賴關系傳遞的三種方式:
1)接口傳遞;
2)構造方法傳遞;
3)setter方法傳遞;
在繼承關系中,我們所有引用基類的地方必須能透明地使用其子類的對象。
在子類中盡量不要重寫父類的方法。
繼承會使兩個類的耦合性增強,適當情況下,我們可以通過聚合、組合、依賴來解決問題。
舉例說明:
下圖中B類繼承瞭A類且重寫瞭func1方法。
然後在使用的過程中,容易產生錯誤。比如下圖中本來想調用父類的方法,但是調用瞭子類的重寫方法導致結果錯誤,違反瞭裡氏替換原則。
在實際編程中,我們常常會通過重寫父類的方法完成新的功能,這樣寫起來雖然簡單,但是整個繼承體系的復用性會比較差,特別是運行多態比較頻繁時。
解決方法:將父類和子類都繼承一個更通俗的基類,原有的繼承關系去掉,采用依賴、聚合、組合的關系替代。
18fa5444e1623a462f8171d2f5671e70使用組合關系降低A、B的耦合度
一個軟件實體,如類、模塊、函數,應該對擴展開放,對修改關閉。用抽象構建框架,用實現擴展細節。
當軟件需要變化時,盡量通過擴展軟件實體的行為來實現變化,而不是通過修改已有的代碼來實現變化。
舉例說明:
下圖為一個畫圖工具類,接受Shape對象,根據其type值來調用不同的方法畫不同的方法。
上述方法的問題:違反瞭開閉原則,當我們要新增一個圖形種類時,要去修改原有GraphicEditor代碼。
改進思路:將draw()方法放入Shape抽象類,讓繼承Shape的圖形子類各自實現自己的draw()方法。這樣在新增圖形後,就隻要新增代碼而不用去修改已有代碼瞭。
又名最少知道原則,一個對象應該對其他對象保持最少的瞭解。對於被依賴的類不關多麼復雜,都盡量將邏輯封裝在類的內部,對外除瞭提供的public方法,不泄露任何信息。
更簡單的定義:隻與直接的朋友通信。
直接的朋友:隻要兩個對象之間有耦合關系(依賴、關聯、組合、聚合等),我們就說這兩個對象之間是朋友關系。其中我們稱出現成員變量、方法參數、方法返回值中的類為直接的朋友,而出現在局部變量中的類不是直接的朋友。即陌生類不要以局部變量的形式出現在類的內部。
盡量使用合成/聚合的方式,而不是使用繼承。
第一種方法:使用依賴關系。
在B的方法中傳入參數類A
第二種方法:使用聚合關系。
在B中添加成員變量A,並用set方法傳入A
第三種方法:使用組合關系。
在B類中添加成員變量A,且通過new創建
1)找出應用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的代碼混在一起。
2)針對接口編程,而不是針對實現編程。
3)為瞭交互對象之間的松耦合設計而努力。
上一篇