目錄
- 一、應該具備的性質
- 二、面向對象設計原則
- 三、詳解
- 3.1 開閉原則
- 3.2 單一職責原則
- 3.3 里氏替換原則
- 3.4 依賴倒置原則
- 3.5 接口隔離原則
- 3.6 合成復用原則
- 3.7 迪米特原則
一、應該具備的性質
- 可擴展性
- 靈活性
- 可插入性
二、面向對象設計原則
以下設計原則的重要性從高到低排列
名稱 | 簡介 | 重要度 |
---|---|---|
開閉原則 | 軟件實體對擴展是開放的,但對修改是關閉的,即在不修改一個軟件實體的基礎上去擴展其功能 | 💪💪💪💪💪 |
依賴倒置原則 | 要針對抽象層編程,而不要針對具體類編程 | 💪💪💪💪💪 |
單一職責原則 | 類的職責要單一、不能將太多的職責放在一個類中 | 💪💪💪💪 |
里氏替換原則 | 在軟件系統中,一個可以接受基類對象的地方必然可以接受一個子類對象 | 💪💪💪💪 |
合成復用原則 | 在系統中應該盡量多使用組合和聚合關聯關系,盡量少用甚至不用繼承關系 | 💪💪💪💪 |
迪米特法則 | 一個軟件實體對其他實體的引用越少越好,或者說如果兩個類不必彼此直接通信,那么這兩個類就不應當發生直接的相互作用,而是通過引入一個第三者發生間接交互 | 💪💪💪 |
接口隔離原則 | 使用多個專門的接口來取代一個統一的接口 | 💪💪 |
三、詳解
3.1 開閉原則
- 抽象化是開閉原則的關鍵。
- 要求開發人員可以在不修改系統中現有功能代碼的前提下,實現對應用系統的軟件功能進行擴展。
3.2 單一職責原則
- 高內聚性原則
- 避免相同的職責(功能)分散到不同的類中實現
- 避免一個類承擔過多的職責
- 可以減少類之間的耦合
- 數據庫類設計示例
- 數據庫連接和數據庫訪問操作相互分離
- 例如數據庫連接分為Mysql和Orcal連接
- 相應的訪問也會有Mysql和Orcal訪問
3.3 里氏替換原則
- 凡是父類出現的地方,都可以用子類進行替代
- 里氏替換原則
- 子類可以實現父類的抽象方法,但不能覆蓋父類的非抽象方法
- 子類中可以增加自己特有的方法
- 當子類的方法重載父類的方法時,方法的形參要比父類方法的輸入參數更寬松
- 當子類的方法實現父類的抽象方法時,方法的返回值要比父類更嚴格。
3.4 依賴倒置原則
- 將依賴關系倒置為依賴接口
- 上層模塊不應該依賴于下層模塊,它們共同依賴于一個抽象
- 父類不能依賴子類,它們都要依賴抽象類
- 抽象不能依賴于具體,具體應該依賴于抽象
- 示例如下
- 左圖顯示了類之間的嚴格依賴,耦合性非常強
- 應該做如下修改
- 找到類之間共同的行為約束(接口)
- 客戶端程序不針對具體的類進行調用,而是調用接口
- 這樣就屏蔽了類之間的強關聯關系
3.5 接口隔離原則
- 一個類對另外一個類的依賴性應當是建立在最小的接口上
- 客戶端不應該依賴那些它不需要的接口(方法)
- 仍然需要考慮接口的單一職責原則
- 如何避免不良好的接口設計
- 用多個專門的接口,而不使用單一的總接口
- 一個接口就只代表一個角色
- 使用接口隔離原則拆分接口時,首先必須滿足單一職責原則
3.6 合成復用原則
- 也稱為組合/聚合復用原則
- 盡量使用對象組合,而不是繼承來達到復用目的
- 一個新的對象里通過關聯關系(包括組合關系和聚合關系)來使用一些已有的對象
- 新對象通過委派調用已有對象的方法達到復用其已有功能的目的
- 簡單來說,就是要盡量使用組合/聚合關系,少用繼承!
- 繼承復用: 實現簡單,易于擴展,沒有足夠的“靈活性”(“白箱”復用)
- 上面的類
StudentDAO
擁有了DBUtil
類的行為以及屬性 - 那么兩個類之間具有了強耦合關系,尤其是
DBUtil
父類發生改變時,其子類StudentDAO
和TeacherDAO
都會受到影響。 - 組合/聚合復用:耦合度相對較低,選擇性地調用成員對象的操作;可以在運行時動態進行(“黑箱”復用)
- 讓類
StudentDAO
擁有了DBUtil
類的實例 - 此時
StudentDAO
類依然擁有了DBUtil
類的屬性和行為 - 如此以來耦合性就會降低
- 如果想近一步降低耦合性,則將
DBUtil
類設計為接口,在其它地方實現即可。
- 讓類
3.7 迪米特原則
- 要求一個軟件實體應當
盡可能少
的與其他實體發生相互作用 - 又稱為最少知識原則
- 不要和“陌生人”說話
- 只與你的直接朋友通信
- 每一個軟件單位對其他的單位都只有最少的知識,而且局限于那些本單位密切相關的軟件單位
- 簡單來說就是,創建松耦合的類
- 某系統界面類(如Form1、Form2等類)與數據訪問類(如DAO1、DAO2等類)之間的調用關系較為復雜,如圖所示
- 如果其中的一個類需要調用另一個類的某一個方法的話,可以通過第三者轉發這個調用