所有的設計模式都是爲了解決變化的問題,通過一定的模式來應對變化,變化應對的原則是開放封閉原則,對修改封閉,對擴展開放。
爲了應對變化,就會添加相應的層次,層次越多,代碼的顆粒就越小,那麼代碼就越複雜。
所以設計時考慮變化和複雜之間的取捨,爲了應對變化 ,需要使用模式,但是又不可以一味應用模式,導致代碼太複雜。
應該是根據軟件可能的變化部分使用模式應對變化。
里氏代換原則:子類型必須能夠替換掉它的父類型,is a關係。
A 策略模式
現實模型:不同的實現部分,但是他們的對外接口是一樣的。
設計模式:抽象多一層,外部只調用基類,不調用具體的策略類。
B 合成模式
現實模型:數據是樹型結構,而且樹節點之間存在整體和部分的包含關係。
設計模式:將樹節點的樹枝和樹葉同等對待,他們具有一樣的基類。
這樣就可以很容易的生成任何類型樹結構。
C 代理模式
現實模型:外部希望訪問真實的對象,但是設計者因爲各種原因,可能性能或者安全考慮,讓一個代理和外部打交道,我們現實也經常有代理,委託某個人幫助實施部分功能。
設計模式:代理和真實對象存在關聯,然後他們繼承一樣的基類,那麼就對外有統一的功能,
結論:里氏代換原則實現方法都是一樣的,就是繼承同樣的基類,然後外部通過和基類打交道,基類就是這個中間層次,只要基類不變化,那麼就可以保存對外接口不變化。
通過添加基類,對修改封閉,對擴展開放。
上面3個現實的模型是不一樣的,策略之間對等關係,合成是整體和部分關係,但是把他們對等看待,代理模式是關聯關係,但是對外他們是對等關係。
要是現實模型的AB不滿足里氏代換原則,就算B不is a A ,那麼這個時候如何解決他們的關係的呢?
A 添加 基類C,讓他們同時繼承C
正方形和長方形的例子,正方形不是長方形,通過引入C 四邊形解決。
B 繼承關係改爲委派關係
依賴倒轉原則:A 高層不應該依賴低層,兩個都應該依賴抽象。
B 抽象不應該依賴細節,細節應該依賴抽象。
A 工廠方法現實模型:外部需要調用一個對象,需要new一個對象,依賴於具體對象。
設計模式:添加一個工廠類,將這個類的實例化延遲到之類,外部就是依賴抽象,而不依賴具體類型。
B 模板對象
現實模型:兩個東西,大部分是一樣的,但是有些細節不一樣,那麼將公共部分抽象爲模板,不同播放延遲到子類實現。
設計模式:抽象公共部分爲基類,定義接口虛函數,延遲到子類實現。
C 迭代器模式
現實模型:需要迭代功能。只是迭代的類型不一樣。
解決辦法:統一基類迭代器,具體迭代接口函數在具體子類實現。
依賴倒轉原則,創建類的時候要不依賴具體,那麼就要創建工廠類,麻煩。同時依賴倒轉假設具體類是被修改的也是不總正確的 ,所以就是要合理使用。
接口隔離原則:應該給客戶端提供儘可能小的接口,而不要提供大接口。
合成聚合複用原則:要儘量使用合成聚合,而不要使用繼承。
區分Has-A 和Is -a ,Is -A 表示一個類是另一個類的一種。Has-A表是某一個角色具有某一項職責。
Has-A用關聯,Is-A用繼承。
迪米特法則:如果兩個類不必彼此直接通信,那麼這兩個類就不應發生直接的相互作用,如果其中一個類需要調用另一個類的某個方法,就通過第三者轉發這個調用。
說白了就是模塊化設計,高內聚,低耦合。
高內聚:單一職責原則。
低耦合:迪米特法則 接口隔離原則 依賴倒轉原則
目的是對修改封閉,對擴展開放。
代碼複用:封裝,繼承 。
通過抽象封裝,繼承,是代碼可以服用。
封裝的原則是:高內聚, 單一職責。
適應變化:多態機制,添加層次。
通過運用多態和添加代碼層,可以讓代碼適應變化。
層次的原則:低內聚,迪米特法則 接口隔離原則 依賴倒轉原則
軟件要易於維護和適應變化,一個複用率好的系統就是一個容易維護的系統,一個適應變化的系統是對修改封閉對擴展開發的系統。
所以代碼設計的原則是複用和適應變化。