連載:麵向對象葵花寶典:思想、技巧與實踐(31) - OCP原則
開閉原則是一個大部分人都知道,但大部分人都不懂的設計原則!
====================================================================
OCP,Open-Closed Principle,中文翻譯為“開閉原則”。
當我第一次看到OCP原則時,我的感覺就是這原則也太抽象了吧,什麼開,什麼閉呢?
然後我去尋找更加詳細的答案,最經典也是最常見的解釋就是維基百科了:
https://en.wikipedia.org/wiki/Open/closed_principle
"software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"; |
翻譯一下就是:對擴展開放,對修改封閉!
雖然這句解釋更詳細了,但其實還是很難理解,我因此去請教了一個前輩高人,他的回答更加驚世駭俗:不修改代碼就可以增加新功能!!
當時我聽到這句話就震驚了,這是多麼神奇的事情啊,不修改代碼就能夠增加新功能!
但問題是:怎麼做到的呢?難道這個原則是有關人工智能,又或者有什麼高超的技巧,能夠做到不修改代碼增加新功能?
這麼牛逼的原則當然要繼續探索了,但怎麼也沒有找到“不修改代碼就可以增加新功能”的獨門秘籍!
於是對這個原則有了懷疑,經過繼續的探索和查看各種資料,才發現原來是各位大師們在解釋這個原則的時候隱藏了非常重要的“主語”,而這才是OCP原則的關鍵!
大師們省略的主語一個就是consumer(翻譯成使用者、消費者),一個就是provider(翻譯成生產者、提供著),例如A類調用了B類的方法,則A就是consumer,B就是provider。
完整的OCP原則實際上應該這樣表述:open for provider extension,closed for consumer modification,翻譯一下就是:對使用者修改關閉,對提供者擴展開放!
更通俗的意思就是:提供者增加新的功能,但使用者不需要修改代碼!
雖然到這裏我們已經基本上將OCP原則解釋清楚了,但實際上細心的朋友還是會發現有問題的:提供者增加新的功能,使用者不修改代碼就能用上麼?
比如說:你設計一款有關車遊戲,需要設計一個“car”的類,這個類原來有“加速”、“刹車”、“轉向”三個功能,現在你要加一個新功能“改裝”,遊戲中其它類例如player,不修改代碼就可以用上“改裝”這個功能麼?
很顯然這是不可能的,我都新加了一個函數,你都不調用就能用新的功能,這也太邪乎了吧?
答案在於所謂的增加新功能,並不是增加一個全新的功能,而是原有的功能有了替代實現,這也是英文的“extension”所隱含的深意!
繼續以賽車car作為例子,假設現在你設計了“卡車”、“跑車”、“家用車”三種車,現在要增加一種車“卡丁車”,隻要“卡丁車”也實現了“加速”、“刹車”、“轉向”,那麼player不需要修改代碼,就可以玩“卡丁車”了;但如果你增加了一種“改裝”的功能,那麼player必須修改才能使用“改裝”功能。
對應到代碼上來說,OCP的應用原則如下:
1) 接口不變:包括函數名、函數參數、函數返回值等,可以應用OCP
2) 接口改變:已有函數修改名稱、參數、返回值,或者增加新的函數,OCP都不再適應
雖然OCP原則是針對類設計提出來的原則,但其思想其實適應很廣,係統和係統、子係統和子係統、模塊和模塊之間都可以應用OCP原則,而且不同的地方應用其實都是遵循同一個原則:通過接口交互!例如:
1) 類之間應用OCP:使用interface進行交互;
2)模塊和模塊、係統和係統:使用規定好的協議,不管是私有的還是公開的,例如HTTP、SOAP
================================================
轉載請注明出處:https://blog.csdn.net/yunhua_lee/article/details/25772449
================================================
最後更新:2017-04-03 12:56:39