算是讀書筆記吧
極客時間--設計模式之美
開閉原則 -- OCP(Open Closed Principle)
software entities (modules, classes, functions, etc.) should be open for extension , but closed for modification
軟件實體(模塊、類、方法等)應該“對擴展開放、對修改關閉”
對拓展開放是爲了應對變化(需求),對修改關閉是爲了保證已有代碼的穩定性。
舉個幾個最簡單的反例:如果你的方法的具體行爲,有很多地方耦合這各種基於業務類型的if/else,那麼他一定是違反開閉原則的。
void calloutMethod {
if (type == ModeA) {
//打電話
} else (type == ModeB) {
//發短信
} else (type == ModeC) {
//發視頻
}
}
void doneMethod {
if (type == ModeA) {
//打電話結束
} else (type == ModeB) {
//發短信結束
} else (type == ModeC) {
//發視頻結束
}
}
void comingCallMethod {
if (type == ModeA) {
//收到電話
} else (type == ModeB) {
//收到短信
} else (type == ModeC) {
//收到視頻
}
}
上面的例子做了很多簡化,一旦代碼複雜起來。如果我們想要開發一個新的功能,或者對某個功能做定製,就無法保證對其他功能沒有影響。
void configXXXX() {
//基本操作...
}
//修改後
void configXXXX(isModeA , isModeB) {
//基本操作...
if (isModeA) {
//特殊操作...
}
//基本操作...
if (isModeB) {
//特殊操作
}
//基本操作...
if (isModeA && !isModeB) {
//特殊操作...
} else if (isModeA){
//特殊操作...
}
//基本操作...
}
這個情況對於很多開發人員都很常見,尤其在修改迭代他人代碼的時候。
這種打補丁的方式,隨着補丁的增多,對項目也是毀滅性的。
-
修改和擴展
- 開閉原則並不是說完全杜絕修改
有些功能無論你怎樣設計,都難免要面臨修改。所以我們要儘量以最小的修改代碼的代價來完成新功能的開發。
比如修改方法內部的邏輯。無論你如何設計,都要牽扯到迴歸測試。
- 修改的定義,有時也很主觀
同樣的代碼改動,在粗代碼粒度下,可能被認定爲“修改”;在細代碼粒度下,可能又被認定爲“擴展”。
比如在模塊內添加一個屬性,以滿足新業務需要。這個操作對於類,屬於修改。對於該類的使用方,屬於擴展。
如果你要修改一處代碼,更落地、更容易量化的標準是:
只要它沒有破壞原有的代碼的正常運行,沒有破壞原有的單元測試,我們就可以說,這是一個合格的代碼改動。
-
開閉原則的擴展性是很多設計思想、模式的指導思想與最終目的
多態、依賴注入、基於接口而非實現編程,以及大部分的設計模式(比如,裝飾、策略、模板、職責鏈、狀態)。