變化是復用的天敵!面向對象設計最大的優勢在于:抵御變化!
重新認識面向對象
- 理解隔離變化
- 從宏觀層面來看,面向對象的構建方式更能適應軟件的變化,能夠將變化所帶來的影響減為最小
- 各司其職
- 從微觀層面來看,面向對象的方式更強調各個類的“責任”(接口一樣,實現不一樣)
- 由于需求變化導致的新增類型不應該影響原來類型的實現————是所謂各負責任
- 對象是什么?
- 從語言實現層面來看,對象封裝了代碼和數據。
- 從規格層面講,對象是一系列可被使用的公共接口。
- 從概念層面講,對象是某種擁有責任的抽象。
面向對象設計原則
- 依賴倒置原則(DIP)
- 高層模塊(穩定)不應該依賴于底層模塊(變化),二者都依賴于抽象(穩定)。
- 抽象(穩定)不應該依賴于實現細節(變化),實現細節應依賴于抽象(穩定)。
- 開發封閉原則(OCP)
- 對擴展開放,對更改封閉。
- 類模塊應該是可擴展的,但是不可修改。
- 單一職責原則(SRP)
- 一個類應該僅有一個引起它變化的原因。
- 變化的方向隱含著類的責任。
- Liskov替換原則(LSP)
- 子類必須嫩鞏固替換它們的基類(IS-A)。
- 繼承表達類型抽象。
- 接口隔離原則(ISP)
- 不應該強迫客戶程序依賴它們不用的方法。
- 接口應該小而完備。
- 優先使用對象組合,而不是類繼承
- 類繼承通常為“白箱復用”,對象組合通常為“黑箱復用”。
- 繼承在某種程度上破壞了封裝性,子類父類耦合度高。
- 而對象組合則要求被組合的對象具有良好定義的外部接口,耦合度低。
- 封裝變化點
- 使用封裝來創建對象之間的分界層,讓設計者可以在分界層的一側進行修改,而不會對另一側產生不良的影響,從而實現層次間的松耦合。
- 針對接口編程,而不是針對實現編程
- 不將變量類型聲明為某個特定的具體類,而是聲明為某個接口。
- 客戶程序無需獲知對象的具體類型,只需要知道對象所具有的接口。
- 減少系統中各部分的依賴關系,從而實現“高內聚,松耦合”的類型設計方案。
面向接口設計
產業強盛的標志:接口標準化!
- 統一六國的秦,其兵器不論東西南北都擁有統一標準
- 活字印刷術,區別于雕版印刷的死板
將設計原則提升為設計經驗
- 設計習語Design Idioms
- Design Idioms描述與特定編程語言相關的底層模式,技巧,慣用法。
- 設計模式Design Patterns
- Design Patterns主要描述的是“類與相互通信的對象之間的組織關系”,包括它們的角色、職責、協作方式等方面。
- 架構模式Architectural Patterns
- Architectural Patterns描述系統中與基本結構組織關系密切的高層模式,包括子系統劃分,職責,以及如何組織它們之間關系的規則。