前言:這篇繼續來看看開閉原則。廢話少說,直接入正題。
軟體設計原則系列文章索引
開閉原則,英文縮寫ocp,全稱open closed principle。
原始定義:software entities (classes, modules, functions) should be open for extension but closed for modification。
字面翻譯:軟體實體(包括類、模組、功能等)應該對擴充套件開放,但是對修改關閉。
一般情況,我們接到需求變更的通知,通常方式可能就是修改模組的源**,然而修改已經存在的源**是存在很大風險的,尤其是專案上線執行一段時間後,開發人員發生變化,這種風險可能就更大。所以,為了避免這種風險,在面對需求變更時,我們一般不修改源**,即所謂的對修改關閉。不允許修改源**,我們如何應對需求變更呢?答案就是我們下面要說的對擴充套件開放。
通過擴充套件去應對需求變化,就要求我們必須要面向介面程式設計,或者說面向抽象程式設計。所有引數型別、引用傳遞的物件必須使用抽象(介面或者抽象類)的方式定義,不能使用實現類的方式定義;通過抽象去界定擴充套件,比如我們定義了乙個介面a的引數,那麼我們的擴充套件只能是介面a的實現類。總的來說,開閉原則提高系統的可維護性和**的重用性。
下面就結合之前博主在園子裡面看到的乙個使用場景來一步步呈現使用實現類程式設計的弊端。
場景說明:馬上中秋節了, **公司希望研發部門研發一套工具,實現給公司所有員工傳送祝福郵件。
接到開發需求,研發部立刻開會成立研發小組,進入緊張的開發階段,經過1個月的艱苦奮戰,系統順利上線。**實現如下:
namespaceutility
}}
namespaceservice
//節日問候
public
void greeting(string
strmsg)
}}
classprogram
}
一切都很順利,系統也得到公司好評。
日復一日,年復一年,隨著時間的推移,公司發現郵件推送的方式也存在一些弊病,比如某些網路不發達地區不能正常地收到郵件,並且在外出差人員有時不能正常收到郵件。這個時候公司領導發現簡訊推送是較好的解決辦法。於是乎,需求變更來了:增加簡訊推送節日祝福的功能,對於行政部等特殊部門保留郵件傳送的方式。
研發部的同事們雖然已有微言,但是沒辦法,也只有咬著牙忙了,於是**變成了這樣。
namespaceutility
}//傳送簡訊的類
public
class
phonemessage
}}
namespaceservice
public
class
messageservice
else
if (otype ==messagetype.phone)
}//節日問候
public
void greeting(string
strmsg)
else
if (m_otype ==messagetype.phone)}}
}
classprogram
}
經過一段時間的加班、趕進度。終於大功告成。
事情發展到這裡,就可以看出使用實現類去程式設計,你會因為需求變更而死得很慘,這個時候我們就能看出遵守開閉原則的重要性了,如果這個系統設計之初就能考慮這個原則,所有的可變變數使用抽象去定義,可能效果截然不同。
如果專案設計之初我們定義乙個isendable介面,我們看看效果怎樣呢?
namespaceihelper
}
namespaceutility
}//傳送簡訊的類
public
class
phonemessage:isendable
}//public
class
wechatmessage:isendable
}}
namespaceservice
//節日問候
public
void greeting(string
strmsg)
}}
classprogram
}
設計分析:在messageservice服務類中,我們定義了isendable的介面變數m_osendhelper,通過這個介面變數,我們就能很方便的通過擴充套件去應對需求的變化,而不必修改原來的**。比如,我們現在再增加一種新的推送方式,對於我們的messageservice服務類來說,不用做任何修改,只需要擴充套件新的推送訊息的工具類即可。從需要抽象的角度來說,開閉原則和依賴倒置原則也有一定的相似性,不過博主覺得,開閉原則更加偏向的是使用抽象來避免修改源**,主張通過擴充套件去應對需求變更,而依賴倒置更加偏向的是層和層之間的解耦。當然,我們也不必分得那麼細,往往,乙個好的設計肯定是遵循了多個設計原則的。
上面的設計,很好的解決了messageservice服務類中的問題,但是對於呼叫方(比如上文中的main函式裡面),很顯然是違背了依賴倒置原則的,因為它既依賴介面層isendable,又依賴介面實現層emailmessage、phonemessage等。這肯定是不合適的。我們引入mef,稍作修改。
namespaceutility
}//傳送簡訊的類
[export("
phone
", typeof
(isendable))]
public
class
phonemessage:isendable
}// [export("
", typeof
(isendable))]
public
class
wechatmessage:isendable
}}
main函式裡面
classprogram
[import(
"phone
", typeof
(isendable))]
public isendable ophonehelper
[import(
", typeof
(isendable))]
public isendable owechathelper
static
void main(string
args)
}
如果你使用unity,直接用配置檔案注入的方式更加簡單。
C 軟體設計 小話設計模式原則之 開閉原則OCP
前言 這篇繼續來看看開閉原則。廢話少說,直接入正題。軟體設計原則系列文章索引 開閉原則,英文縮寫ocp,全稱open closed principle。原始定義 software entities classes,modules,functions should be open for extens...
設計模式 軟體設計原則
軟體設計六大原則 一 單一職責原則 srp 意思是就乙個類而言只有乙個改變類的起因和動機 遵循單一職責 1.可以降低類的複雜度,乙個類只負責一項職責,其邏輯肯定要比負責多項職責簡單的多 2.提高類可維護性,系統的可擴充套件性 3.變更引起的風險降低,當修改乙個功能時,可以顯著降低對其他功能的影響。二...
軟體設計原則 設計模式
定義 高層模組不能依賴底層模組,二者應該依賴其抽象 抽象不依賴細節,細節應該依賴抽象 優點 減少類之間的耦合性,提高系統穩定性 可讀性和可維護性,降低修改程式帶來的風險 定義 不要存在多於乙個導致類變更的原因,乙個類 介面 方法只負責一項職責 優點 降低類的複雜度 提高類的可讀性,提高系統的可維護性...