軟體開發: 唯一不變的是變化: 不管設計的多好,隨著時間推移,應用必定成長和變更 設計原則: 封裝變化:設別應用中變化的方面,把它們和不變的方面分開; (把會變化的部分取出並封裝,這樣,就可以修改或者擴展這個部分,而不會影響其他不需要變化的部分) 針對介面編程,而不是針對實現編程(介面,實際上就是針 ...
軟體開發:
唯一不變的是變化:
不管設計的多好,隨著時間推移,應用必定成長和變更
設計原則:
- 封裝變化:設別應用中變化的方面,把它們和不變的方面分開;
(把會變化的部分取出並封裝,這樣,就可以修改或者擴展這個部分,而不會影響其他不需要變化的部分)- 針對介面編程,而不是針對實現編程(介面,實際上就是針對超類型編程(抽象類型有抽象類和介面))
- 優先使用組合而不是繼承
01 最初
類-->繼承
(缺點:代碼重覆;代碼的局部更新導致非局部的副作用)
不一致的方法使用介面
(因為介面沒有實現代碼,所以摧毀了這些方法的代碼復用;
如果需要修改一個行為,那麼需要追蹤到所有定義了該行為的子類並修改它)
02 改進
want:需要變更時,使用對現有代碼影響最小的方式;花更少的時間重寫代碼
-
分離變和不變(根據設計原則①)
把子類不一致的方法從父類抽取出來,並創建一組新的類來表示每個方法 -
介面編程(根據設計原則②)
使用介面表示每個方法,方法的每個實現將實現其中一個介面;
(方法類繼承介面;而不是子類或者父類實現介面)
!!復用+脫離繼承所帶來的包袱
【這個設計:其他對象就可以復用介面的實現方法,而且這些方法不在父類中;如果增加新的介面實現,不會修改已有的實現類,也不會影響使用方法的子類】
子類將使用介面所表示的方法
03整合
整合:父類委托介面,而不是使用
- 添加實例變數(類型為介面類型)
(在運行時,具體對象會給變數分配特定行為)- 修改不一致的方法:
fly()-->performFly()
Public abstract class Duck{
FlyBehavior flyBehavior;
【創建子類,在構造方法中flyBehavior = new FlyWithWings();】
Public void performFly(){
flyBehavior.fly();【創建對象後,會根據介面的實現自動分配特定行為】
}
}
針對實現編程了(在構造器庫實現介面);
(雖然有很多彈性,但是在初始化實例變數上做的糟糕)
04 優化
want:如何實現一個對象,其方法可以在運行時改變
動態設置行為;
不是在構造器中實例化;
public void setFlyBehavior(FlyBehavior fb){
flyBehavior = fb;
}
Duck model = new ModelDuck();
Model.setFlyBehavior(new FlyWithRocket());
修改行為,就可以直接調用setter方法改;
以上就是策略模式的情況:
策略模式:
定義一個演算法族(行為類),分別封裝起來,使得它們之間可以互相變換;策略讓演算法的變化獨立於使用它的客戶
OO工具箱
OO基礎:抽象、封裝、多態、繼承
OO原則:
封裝變化
優先使用組合而不是繼承
針對介面編程,而不是針對實現編程。
OO模式:策略模式
要點
1.知道OO基礎,還不能你成為好的OO設計人員。
2.良好的OO設計是可復用、可擴展和可維護的
3.模式耍瘁向你哭布搬叭甭痘腹示如何建造具有良好00設計質量的系統。
4.模式是歷經驗證的00經驗。
5.模式不給你代碼,而是針對設計問題給出通用的解決方案。你把它們用到特定的應用中
6.模式不是被髮明,而是被髮現。
7.大多數的模式和原則,都著眼於軟體中的變化這個主題。
8.大多數模式允許系統的某些部分獨立於其他部分而變化。
9.我們經常嘗試把系統中會變化的部分抽出來封裝
10.模式提供了一種共用的語言,能最大化你和其他開發人員溝通的價值