單一職責原則(srp):乙個類應當只有乙個改變的原因,類只需要知道一件事情,它們應當有乙個單獨的職責,要點就是當乙個類需要改變時,應當只有乙個原因。
開放-封閉原則(ocp):軟體實體(類、模組、函式等)應當為擴充套件而開放,又為修改而封閉。這個原則有乙個相當詳細的定義,但是乙個簡單的意思是:你應當能夠改變乙個模組的周邊環境而無須改變模組本身。
liskov替換原則(lsp):子型別(subtypes)必須是為它們的基型別(base types)可替代的。
依存關係倒置原則(dip) :a.高層模組應當不依賴低層模組,它們應當依賴於抽象。
b.抽象應當不依賴於細節,細節應當依賴於抽象。
更好的描述是:不要依賴那些容易變化的具體類。如果你要繼承乙個類,從乙個抽象類繼承吧。如果你要持有乙個類的引用,從乙個抽象的類引用吧。如果你要呼叫乙個函式,從乙個抽象的函式呼叫吧。
介面隔離原則(isp):客戶不應當依賴那些它們根本不用的方法。
總結:五個簡單的原則是:
1、srp--乙個類應當只有乙個發生變化的原因。
2、ocp――應當能夠改變乙個類的環境,而無須改變類本身。
3、lsp――避免造成派生類的方法非法或退化,乙個基類的使用者應當不需要知道這個派生類。
4、dip ――用依賴於介面和抽象類來替代依賴容易變化的具體類。
5、isp――給乙個物件的每乙個使用者乙個介面,這個介面僅有使用者需要的方法。
正 如牛頓三大定律在經典力學中的位置一樣,「開-閉」原則(open-closed principle)是物件導向的可復用設計(object oriented design或ood)的基石。其他設計原則(黎克特制代換原則、依賴倒轉原則、合成/聚合復用原則、迪公尺特法則、介面隔離原則)是實現「開-閉」原則的手段 和工具。
一、「開-閉」原則(open-closed principle,ocp)
1.1「開-閉」原則的定義及優點
1)定義:乙個軟體實體應當對擴充套件開放,對修改關閉( software entities should be open for extension,but closed for modification.)。即在設計乙個模組的時候,應當使這個模組可以在不被修改的前提下被擴充套件。
2)滿足「開-閉」原則的系統的優點
a)通過擴充套件已有的軟體系統,可以提供新的行為,以滿足對軟體的新需求,使變化中的軟體系統有一定的適應性和靈活性。
b)已有的軟體模組,特別是最重要的抽象層模組不能再修改,這就使變化中的軟體系統有一定的穩定性和延續性。
c)這樣的系統同時滿足了可復用性與可維護性。
1.2如何實現「開-閉」原則
在物件導向設計中,不允許更改的是系統的抽象層,而允許擴充套件的是系統的實現層。換言之,定義乙個一勞永逸的抽象設計層,允許盡可能多的行為在實現層被實現。
解決問題關鍵在於抽象化,抽象化是物件導向設計的第乙個核心本質。
對乙個事物抽象化,實質上是在概括歸納總結它的本質。抽象讓我們抓住最最重要的東西,從更高一層去思考。這降低了思考的複雜度,我們不用同時考慮那麼多的東西。換言之,我們封裝了事物的本質,看不到任何細節。
在物件導向程式設計中,通過抽象類及介面,規定了具體類的特徵作為抽象層,相對穩定,不需更改,從而滿足「對修改關閉」;而從抽象類匯出的具體類可以改變系統的行為,從而滿足「對擴充套件開放」。[page]
對實體進行擴充套件時,不必改動軟體的源**或者二進位制**。關鍵在於抽象。
1.3對可變性的封裝原則
「開-閉」原則也就是「對可變性的封裝原則」(principle of encapsulation of variation ,evp)。即找到乙個系統的可變因素,將之封裝起來。換言之,在你的設計中什麼可能會發生變化,應使之成為抽象層而封裝,而不是什麼會導致設計改變才封 裝。
「對可變性的封裝原則」意味著:
a)一種可變性不應當散落在**的許多角落,而應當被封裝到乙個物件裡面。同一可變性的不同表象意味著同乙個繼承等級結構中的具體子類。因此,此處可以期待繼承關係的出現。繼承是封裝變化的方法,而不僅僅是從一般的物件生成特殊的物件。
b)一種可變性不應當與另一種可變性混合在一起。作者認為類圖的繼承結構如果超過兩層,很可能意味著兩種不同的可變性混合在了一起。
使用「可變性封裝原則」來進行設計可以使系統遵守「開-閉」原則。
即使無法百分之百的做到「開-閉」原則,但朝這個方向努力,可以顯著改善乙個系統的結構。
二、黎克特制代換原則(liskov substitution principle, lsp)
2.1概念
定義:如果對每乙個型別為t1的物件o1,都有型別為t2 的物件o2,使得以t1定義的所有程式p在所有的物件o1都代換為o2時,程式p的行為沒有變化,那麼型別t2是型別t1的子型別。
即,乙個軟體實體如果使用的是乙個基類的話,那麼一定適用於其子類。而且它覺察不出基類物件和子類物件的區別。也就是說,在軟體裡面,把基類都替換成它的子類,程式的行為沒有變化。
反過來的代換不成立,如果乙個軟體實體使用的是乙個子類的話,那麼它不一定適用於基類。
任何基類可以出現的地方,子類一定可以出現。
基於契約的設計、抽象出公共部分作為抽象基類的設計。
2.2黎克特制代換原則與「開-閉」原則的關係
實現「開-閉」原則的關鍵步驟是抽象化。基類與子類之間的繼承關係就是抽象化的體現。因此黎克特制代換原則是對實現抽象化的具體步驟的規範。
違反黎克特制代換原則意味著違反了「開-閉」原則,反之未必。
三、 依賴倒轉原則(dependence inversion principle, dip)
3.1概念
依賴倒轉原則就是要依賴於抽象,不要依賴於實現。(abstractions should not depend upon details. details should depend upon abstractions.)要針對介面程式設計,不要針對實現程式設計。(program to an inte***ce, not an implementation.)
也就是說應當使用介面和抽象類進行變數型別宣告、引數型別聲 明、方法返還型別說明,以及資料型別的轉換等。而不要用具體類進行變數的型別宣告、引數型別宣告、方法返還型別說明,以及資料型別的轉換等。要保證做到這 一點,乙個具體類應當只實現介面和抽象類中宣告過的方法,而不要給出多餘的方法。
傳統的過程性系統的設計辦法傾向於使高層次的模組依賴於低層次的模組,抽象層次依賴於具體層次。倒轉原則就是把這個錯誤的依賴關係倒轉過來。
物件導向設計原則
oo原則 封裝變化 多用組合,少用繼承 針對介面程式設計,不針對實現程式設計 為互動物件之間的松耦合而努力 類應該對擴充套件開放,對修改關閉 依賴抽象,不要依賴具體類 只和朋友交談 別找我,我會找你 類應該只有乙個改變的理由 從設計原則到設計模式 針對介面程式設計,而不是針對實現程式設計 客戶無需知...
物件導向設計原則
物件設計原則 物件導向設計原則 物件導向設計的基石是 開 閉 原則。開一閉 原則講的是 乙個軟體實體應當對擴充套件開放,對修改關閉。這個規則說的是,在設計乙個模組的時候,應當使這個模組可以在不被修改的前提下被擴充套件。從另外乙個角度講,就是所謂的 對可變性封裝原則 對可變性封裝原則 意味著兩點 1 ...
物件導向設計原則
oo原則 封裝變化 多用組合,少用繼承 針對介面程式設計,不針對實現程式設計 為互動物件之間的松耦合而努力 類應該對擴充套件開放,對修改關閉 依賴抽象,不要依賴具體類 只和朋友交談 別找我,我會找你 類應該只有乙個改變的理由 從設計原則到設計模式 針對介面程式設計,而不是針對實現程式設計 客戶無需知...