連載:面向對象葵花寶典:思想、技巧與實踐(31) - OCP原則

開閉原則是一個大部分人都知道,但大部分人都不懂的設計原則!驚訝


====================================================================

OCP,Open-Closed Principle,中文翻譯爲“開閉原則”。

 

當我第一次看到OCP原則時,我的感覺就是這原則也太抽象了吧,什麼開,什麼閉呢?

 

然後我去尋找更加詳細的答案,最經典也是最常見的解釋就是維基百科了:

http://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


================================================ 
轉載請註明出處:http://blog.csdn.net/yunhua_lee/article/details/25772449
================================================ 

發佈了137 篇原創文章 · 獲贊 518 · 訪問量 108萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章