OOD設計原則之OCP LSP

2021-06-27 12:24:59 字數 2276 閱讀 5072

一直談軟體設計,卻不能準確的描述。結合最近看《黑客與畫家》,這才對設計的六大原則有了一點淺顯的體會。首先說一下乙個專案的路徑:開發、重構、測試、投產、運維。其中重構的好處就是希望對原有設計和**進行修改(注意:重構的應該分兩個方向:設計上的修改和**上的修改),而運維則是希望儘量減少對原有**的修改,保持歷史**的純淨,提高系統穩定性。

軟體應該保持對擴充套件開放,對修改關閉。開發的時候要允許在已有軟體模組的基礎上進行拓展功能,並盡可能不去修改已有的功能模組。換句話說就是乙個軟體實體應該通過擴充套件來實現變化,而不是通過修改已有**來實現變化。

那麼如何使用這個原則呢?個人認為核心是找到或者預見未來可能發生變化**塊。在具體使用的時候可以考慮:

1、通過使用介面或者抽象類約束擴充套件,並對擴充套件的邊界進行限定,保證出現在介面或抽象類中方法都是有用的方法。

2、引數型別盡可能是介面或者抽象類,而不是某乙個實現類。

3、合理的設計抽象類和介面,也就是盡可能的保持抽象層的穩定,一經確定不允許修改。

4、盡可能的通過元資料來控制模組的行為。簡單點說通過配置引數,來控制模組的模組的功能。引數既可以寫在普通檔案中,也可以儲存在資料庫中。提到這一點就不得不說spring容器,spring就是乙個典型的通過元資料來控制模組行為。僅僅通過元資料控制模組是不夠的,用到極致的是ioc,也就是控制反轉。

5、統一專案約束,團隊中的所有人員必須遵守專案約束,比如說命名規則等。(團隊合作中非常重要)

6、封裝變化,將相同的變化封裝到同乙個介面或者抽象類中,不同的變化封裝到不同 的介面或者抽象類中。也就是多種變化不能共存。

值得注意的是,ocp並不意味著完全不修改已有**。通常而言,底層模組的變化,必須服務於高層模組,也就是耦合。在具體使用中需要根據情況考慮。

開發時,基型別(basetype)能夠被子型別(subtype)替代,充分考慮多型性。換句話說,乙個軟體實體如果使用的是乙個基類,那麼一定適用於其子類,而且無法差別到底是基類物件還是子類物件。比如說有兩個類,乙個是base類,另乙個sub類繼承了base子類。那麼如果乙個方法可以接收乙個基類物件b:method(base b),那麼他必然可以接收乙個子類物件s,也就是method(s)。這樣一看,lsp其不是很簡單麼?當然不是!lsp本質上應該是說在 繼承結構構建的過程中,要合理,而不是濫用!!也就是說不是所有的繼承都是合理的。這裡我們也來說說經典的問題:」正方形不是矩形「。在現實世界中,正方形是矩形。在oo中,正方形和矩形的也應該是is-a的關係,這關係正好是oo中的繼承關係的依據嘛。因此,在設計類的時候,正方形square類應該繼承矩形rectangle類。

package com.ldd.lsp;

public class rectangle

public void setwidth(int width)

public int getheight()

public void setheight(int height)

}

package com.ldd.lsp;

public class square extends rectangle

public void setheight(int height)

}

package com.ldd.lsp;

public class client {

public rectangle addheight(rectangle b){

while(b.getheight()

如果給addheight傳乙個rectangle(長寬不一樣)物件的話,沒問題;但是如果傳乙個square物件的話,我們且不管結果如何,明眼人一眼看出,這addheight方法不適用square物件,說白了違反了lsp原則:對於square必須同時修改width和height,而rectangle可以單獨修改width和height。這個問題反映了現實世界概念和oo概念的區別,雖然oo吉利於描述現實世界,但並不是完全等於。

那麼如何做到lsp呢?

1、從抽象類繼承,而不是實體類繼承。也就是抽象類做父類,之所以這麼考慮是因為實體類中確定了和特定實體相關的方法,而這些方法在子類中也許無用。

2、使用契約式程式設計方法(dbc)。簡單點理解dbc就是,父類中定義子類需要實現的功能,相當於用父類來約束子類的功能。

3、從客戶角度出發,派生類的行為必須和客戶程式對其基類所期望行為的保持一樣。

現在我們來重新考慮一起正方形和長方形問題:無論正方形還是矩形,都是圖形。因此建立抽象類shape,裡邊定義了對圖形的基本操作,而rectangle類和square類繼承shape類。

通過以上,再來看一下lsp就很明了:如何合理的使用繼承才是關鍵。

OOD設計原則

以下內容來自 敏捷軟體開發 原則 模式與實踐 ood設計原則 srp,單一職責原則 就乙個類而言,應該僅有乙個引起它變化的原因 將過多的職責耦合在乙個類中導致了脆弱設計 職責是變化的原因 如果應用程式變化的方式總是導致兩個職責同時變化,則不應該分離他們 把業務規則和持久化子系統繫結在一起是自討苦吃,...

OOD設計原則之開閉原則(OCP)

開閉原則ocp open close principle 被稱作是ood的基石,是ood最重要的原則之一。這個原則由大師bertrand meyer在1988年提出 汗,那個時候恐怕國內還很少人知道oo,甚至計算機為何物 software entities should be open for ex...

OOD設計原則之開閉原則(OCP)

開閉原則ocp open close principle 在維基百科的定義 在物件導向程式設計中,開閉原則規定 軟體中的物件 類,模組,函式等等 應該對擴充套件是開放的,但是對於修改是封閉的 這意味著乙個實體是允許在不改變他的源 的前提下變更他的行為。勃蘭特丶梅耶一般被認為是最早提出開閉原則這一術語...