1、開-閉 原則:指的是一個軟件實體應該對擴展開放,對修改關閉。用面向對象的語言來講就是:不允許修改的是系統的抽象層,允許擴展的是系統的具體實現層。
2、里氏代換原則:一個軟件實體如果使用的是一個基類的話,那么一定適用於其子類,而且它根本不能察覺出基類對象和子類對象的區別。
3、依賴倒轉原則:要求客戶端依賴於抽象耦合。
另一種表述是:要針對接口編程,不要針對實現編程(Program to an interface , not an implementation)。
如果設計師希望遵守“開-閉”原則,那么依賴倒轉原則便是達到要求的途徑。
依賴倒轉原則是OO設計的核心原則,設計模式的研究和應用是以依賴倒轉原則為指導原則的。
4、接口隔離原則:使用多個專門的接口比使用單一的總接口要好,一個類對另外一個類的依賴性應當是建立在最小的接口上的。
通俗點說就是如果一個功能需要依賴多個功能,那個把每個功能都做成單獨的接口開放出來,不要把多個接口合並在一個接口里面提供。
5、合成/聚合復用原則:要盡量使用合成/聚合,盡量不要使用繼承。
繼承復用通過擴展一個已有對象的實現來得到新的功能,基類明顯地捕獲共同的屬性和方法,而子類通過增加新的屬性和方法來擴展超類的實現。繼承是類型的復用。
繼承復用的優點:
-
- 新的實現較為容易,因為超類的大部分功能可通過繼承關系自動進入子類;
- 修改或擴展繼承而來的實現較為容易。
繼承復用的缺點:
-
- 繼承復用破壞封裝,因為繼承將超類的實現細節暴露給子類。“白箱”復用;
- 如果超類的實現發生改變,那么子類的實現也不得不發生改變。
- 從超類繼承而來的實現是靜態的,不可能再運行時間內發生改變,因此沒有足夠的靈活性。
由於合成/聚合可以將已有的對象納入到新對象中,使之成為新對象的一部分,因此新的對象可以調用已有對象的功能,
其優點在於:
-
- 新對象存取成分對象的唯一方法是通過成分對象的接口;
- 成分對象的內部細節對新對象不可見。 “黑箱”復用;
- 該復用支持封裝。
- 該復用所需的依賴較少。
- 每一個新的類可將焦點集中在一個任務上。
- 該復用可在運行時間內動態進行,新對象可動態引用於成分對象類型相同的對象。
缺點:
-
- 通過這種復用建造的系統會有較多的對象需要管理。
- 為了能將多個不同的對象作為組合塊(composition block)來使用,必須仔細地對接口進行定義。
Coad法則由Peter Coad提出,總結了一些什么時候使用繼承作為復用工具的條件。 Coad法則:
只有當以下Coad條件全部被滿足時,才應當使用繼承關系:
-
- 子類是超類的一個特殊種類,而不是超類的一個角色。區分“Has-A”和“Is-A”。只有“Is-A”關系才符合繼承關系,“Has-A”關系應當用聚合來描述。
- 永遠不會出現需要將子類換成另外一個類的子類的情況。如果不能肯定將來是否會變成另外一個子類的話,就不要使用繼承。
- 子類具有擴展超類的責任,而不是具有置換掉(override)或注銷掉(Nullify)超類的責任。如果一個子類需要大量的置換掉超類的行為,那么這個類就不應該是這個超類的子類。
- 只有在分類學角度上有意義時,才可以使用繼承。不要從工具類繼承。
“Is-A”代表一個類是另外一個類的一種;
“Has-A”代表一個類是另外一個類的一個角色,而不是另外一個類的特殊種類。