算是讀書筆記吧
極客時間--設(shè)計(jì)模式之美
開閉原則 -- OCP(Open Closed Principle)
software entities (modules, classes, functions, etc.) should be open for extension , but closed for modification
軟件實(shí)體(模塊堡牡、類富寿、方法等)應(yīng)該“對擴(kuò)展開放区赵、對修改關(guān)閉”
對拓展開放是為了應(yīng)對變化(需求),對修改關(guān)閉是為了保證已有代碼的穩(wěn)定性挖滤。
舉個幾個最簡單的反例:如果你的方法的具體行為,有很多地方耦合這各種基于業(yè)務(wù)類型的if/else浅役,那么他一定是違反開閉原則的斩松。
void calloutMethod {
if (type == ModeA) {
//打電話
} else (type == ModeB) {
//發(fā)短信
} else (type == ModeC) {
//發(fā)視頻
}
}
void doneMethod {
if (type == ModeA) {
//打電話結(jié)束
} else (type == ModeB) {
//發(fā)短信結(jié)束
} else (type == ModeC) {
//發(fā)視頻結(jié)束
}
}
void comingCallMethod {
if (type == ModeA) {
//收到電話
} else (type == ModeB) {
//收到短信
} else (type == ModeC) {
//收到視頻
}
}
上面的例子做了很多簡化,一旦代碼復(fù)雜起來觉既。如果我們想要開發(fā)一個新的功能惧盹,或者對某個功能做定制,就無法保證對其他功能沒有影響瞪讼。
void configXXXX() {
//基本操作...
}
//修改后
void configXXXX(isModeA , isModeB) {
//基本操作...
if (isModeA) {
//特殊操作...
}
//基本操作...
if (isModeB) {
//特殊操作
}
//基本操作...
if (isModeA && !isModeB) {
//特殊操作...
} else if (isModeA){
//特殊操作...
}
//基本操作...
}
這個情況對于很多開發(fā)人員都很常見钧椰,尤其在修改迭代他人代碼的時候。
這種打補(bǔ)丁的方式符欠,隨著補(bǔ)丁的增多嫡霞,對項(xiàng)目也是毀滅性的。
-
修改和擴(kuò)展
- 開閉原則并不是說完全杜絕修改
有些功能無論你怎樣設(shè)計(jì)希柿,都難免要面臨修改秒际。所以我們要盡量以最小的修改代碼的代價來完成新功能的開發(fā)。
比如修改方法內(nèi)部的邏輯狡汉。無論你如何設(shè)計(jì),都要牽扯到回歸測試闽颇。
- 修改的定義盾戴,有時也很主觀
同樣的代碼改動,在粗代碼粒度下兵多,可能被認(rèn)定為“修改”尖啡;在細(xì)代碼粒度下,可能又被認(rèn)定為“擴(kuò)展”剩膘。
比如在模塊內(nèi)添加一個屬性衅斩,以滿足新業(yè)務(wù)需要。這個操作對于類怠褐,屬于修改畏梆。對于該類的使用方,屬于擴(kuò)展奈懒。
如果你要修改一處代碼奠涌,更落地、更容易量化的標(biāo)準(zhǔn)是:
只要它沒有破壞原有的代碼的正常運(yùn)行磷杏,沒有破壞原有的單元測試溜畅,我們就可以說,這是一個合格的代碼改動极祸。
-
開閉原則的擴(kuò)展性是很多設(shè)計(jì)思想慈格、模式的指導(dǎo)思想與最終目的
多態(tài)怠晴、依賴注入、基于接口而非實(shí)現(xiàn)編程浴捆,以及大部分的設(shè)計(jì)模式(比如蒜田,裝飾、策略汤功、模板物邑、職責(zé)鏈、狀態(tài))滔金。