“開-閉”原則(Open-Closed Principle,OCP)的定義及優點
定義:一個軟件實體應當對擴展開放,對修改關閉( Software entitIEs should be open for extension,but closed for modification.)。即在設計一個模塊的時候,應當使這個模塊可以在不被修改的前提下被擴展。
滿足“開-閉”原則的系統的優點:
a)通過擴展已有的軟件系統,可以提供新的行為,以滿足對軟件的新需求,使變化中的軟件系統有一定的適應性和靈活性。
b)已有的軟件模塊,特別是最重要的抽象層模塊不能再修改,這就使變化中的軟件系統有一定的穩定性和延續性。
c)這樣的系統同時滿足了可復用性與可維護性。
如何實現“開-閉”原則
在面向對象設計中,不允許更改的是系統的抽象層,而允許擴展的是系統的實現層。換言之,定義一個一勞永逸的抽象設計層,允許盡可能多的行為在實現層被實現。
解決問題關鍵在於抽象化,抽象化是面向對象設計的第一個核心本質。
對一個事物抽象化,實質上是在概括歸納總結它的本質。抽象讓我們抓住最最重要的東西,從更高一層去思考。這降低了思考的復雜度,我們不用同時考慮那麼多的東西。換言之,我們封裝了事物的本質,看不到任何細節。
在面向對象編程中,通過抽象類及接口,規定了具體類的特征作為抽象層,相對穩定,不需更改,從而滿足“對修改關閉”;而從抽象類導出的具體類可以改變系統的行為,從而滿足“對擴展開放”。
對實體進行擴展時,不必改動軟件的源代碼或者二進制代碼。關鍵在於抽象。
對可變性的封裝原則
“開-閉”原則也就是“對可變性的封裝原則”(Principle of Encapsulation of Variation ,EVP)。即找到一個系統的可變因素,將之封裝起來。換言之,在你的設計中什麼可能會發生變化,應使之成為抽象層而封裝,而不是什麼會導致設計改變才封裝。
“對可變性的封裝原則”意味著:
a)一種可變性不應當散落在代碼的許多角落,而應當被封裝到一個對象裡面。同一可變性的不同表象意味著同一個繼承等級結構中的具體子類。因此,此處可以期待繼承關系的出現。繼承是封裝變化的方法,而不僅僅是從一般的對象生成特殊的對象。
b)一種可變性不應當與另一種可變性混合在一起。作者認為類圖的繼承結構如果超過兩層,很可能意味著兩種不同的可變性混合在了一起。
使用“可變性封裝原則”來進行設計可以使系統遵守“開-閉”原則。即使無法百分之百的做到“開-閉”原則,但朝這個方向努力,可以顯著改善一個系統的結構。