設計模式中的那些原則

Sidney發表於2014-11-02

什麼是設計原則?

設計原則是一組指引,使用他們可以避免不良的設計,不良的設計通常有以下幾點特性:

  • 刻板 - 很難迎合變化,每個變化都會影響到系統中其他的部分.
  • 易崩潰 - 當你修改了系統,會導致系統中其他(非預期的)部分崩潰.
  • 無法複用 - 程式碼無法用在其他系統,因為它們無法從當前系統中抽取出來.

接下來,我們就看看有哪些設計原則?

開閉原則

軟體就像類一樣,模組和功能應該對擴充套件保持開放,但是對(內部)修改做出關閉.

如何理解開閉原則?當有變化來臨時,應該儘量不要更改現有的程式碼(關閉),而是結合業務場景,應用設計模式擴充套件現有現有功能.

開閉原則也同樣適用於模組,庫等的修改.

裝飾者和介面卡是兩個很好的例子.

裝飾者模式在往現有設計假如新功能的時候,並不是修改現有的類(關閉),而是建立新的裝飾類,將現有的類進行封裝,這些裝飾類提供新的功能(開放),並往外提供相同的介面.

介面卡則也是不修改現有程式碼(關閉),建立符合新介面的類(通過抽象類或介面),並通過封裝現有類(開放),達到介面轉換的目的.

依賴倒置原則

這個原則的目的是使得:

  • 上層模組不應該依賴於下層模組(當然下層也不能依賴於上層),他們都應該依賴一箇中間的抽象層.

  • 抽象不能依賴於具體實現.相反,實現應該基於抽象.

解釋一下,上層模組和下層之間僅依賴抽象(抽象類或者介面),試想一下,假如上層模組依賴於下層的具體類,那上層需要new出每個具體的類,假如一個商店有20種筆,每種筆是一個類,那麼這個商店要依賴20個這樣的類,耦合度太高.假如我們為這20個品牌的筆提供一個抽象的介面,那麼我們要的只是一個抽象類的集合.這樣上層和下層會徹底解耦.

另外,我們所有的具體類必須派生自一個抽象類,而不是具體類.這樣的原因是不利於重用,想象一下我們有一天想要將下層元件A全部替換到另一個下層元件B,我們這個具體類的實現會顯得很醜陋:對A合理的父類實現對B可能就不合理,所以我們應該應該依賴於抽象而不是具體類.

下面這個清單可以用來被檢查這個原則:

  • 上層類種屬性不能持有具體類的引用.
  • 下層類不能派生自一個具體類.
  • 不要覆蓋基類中已經覆蓋的方法(所以,基類種最好不要有實現).

抽象工廠是反轉依賴的例子.採用抽象工廠,我們可以將上層對下層具體類的依賴轉變成,對抽象工廠和抽象類(由具體類實現)的依賴,從而達到了上下層的解耦.

單一職責原則

單一職責原則規定了每個類都有應該有一個單一的功能,並且該功能由這個類完全封裝起來.這樣做的好處就是,一個類或者模組應該有且只有一個引起改變的原因.

這個原則很好理解,比如,在web中,內容(html)和樣式(css)應該分開.但是,卻很難做到,以至於有的設計模式不得不犧牲這點,比如組合迭代器模式.

最少知識原則

最少知識原則規定了一個物件應該和哪些物件進行互動,意圖是減少物件之間的依賴關係.這個原則可以被總結為:只和你的密友談話.

最少知識原則規定,對任何物件而言,在該物件的方法內,我們只應該呼叫屬於一下範圍的方法:

  • 該物件本身
  • 被當做方法引數而傳遞進來的物件
  • 此方法所建立或例項化的任何物件
  • 物件的任何元件

這個原則只是指導性的,試想一下假如我們完全按照這個原則,那我們會產生多少個wrapper來封裝物件方法的二級呼叫(呼叫物件方法所返回的物件 的方法).

好萊塢原則

don’t call us, we’ll call you

這句在好萊塢電影中經常出現的臺詞也是一種設計原則,是不是感覺酷酷的?

在軟體過程中,經常有這樣的場景,我們需要”在xxx發生後,呼叫xxx來告訴我”,意思是,我不願意一遍遍地詢問xxx發生了麼,而是讓你主動告訴我們.

想一想,回撥,事件驅動就是這個原則很好的例子.

介面隔離原則

這個原則的意思是:客戶端不應該依賴於他們不使用的介面.

結合場景,介面提供的方法應該只和介面要表達的行為相關,與介面不相關的方法不應該在此介面中提供.比如,一個叫Gun的介面,不應該有zoom()方法,因為不一定所有的槍都有瞄準鏡.

介面隔離帶來的好處是,我們的介面功能劃分明確,一個大的介面會被拆分為更小的介面,從而使軟體的複用性大大增加.

里氏替換原則(待補)

里氏替換原則指出了在物件導向的設計中,什麼時候可以使用繼承,什麼時候不應該適用繼承,以及其中蘊含的原理.里氏替換原則可以被歸納為一句話:子類必須能夠替換成它們的基類。

什麼時候適用繼承?

在一個軟體系統中,子類應該可以替換任何基類能夠出現的地方,並且經過替換以後,程式碼還能正常工作。 當你程式碼中有了 instanceof 或者其他類似根據子類類別不同採取不同的動作時,就應該考慮是否違反了里氏替換原則:表明此處子類不能替換基類,必須要做區分才能正確執行.

參考資料:

依賴倒置:

設計原則:

最小知識原則:

好萊塢原則:

里氏替換原則:

相關文章