## 連載:面向對象葵花寶典:思想、技巧與實踐(31) - OCP原則
開閉原則是一個大部分人都知道,但大部分人都不懂的設計原則!
====================================================================
OCP,Open-Closed?Principle,中文翻譯為“開閉原則”。
?
當我第一次看到OCP原則時,我的感覺就是這原則也太抽象了吧,什么開,什么閉呢?
?
然后我去尋找更加詳細的答案,最經典也是最常見的解釋就是維基百科了:
[http://en.wikipedia.org/wiki/Open/closed_principle](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
- 前言
- (1) - 程序設計思想的發展
- (2) - 面向對象語言發展歷史
- (3) - 面向過程 vs 面向對象
- (4) - 面向對象是瑞士軍刀還是一把錘子?
- (5) - 面向對象迷思:面向對象導致性能下降?
- (6) - 不要說你懂“類”
- (7) - “對象”新解
- (8) - “接口” 詳解
- (9) - “抽象類” 詳解
- (10) - “抽象” 詳解
- (11) - “封裝” 詳解
- (12) - “繼承” 詳解
- (13) - “多態” 詳解
- (14) - 面向對象開發技術流程
- (15) - 需求詳解
- (16) - 需求分析終極目的
- (17) - 需求分析518方法
- (18) - 用例分析
- (19) - 功能點提取
- (20) - 用例圖的陷阱
- (21) - SSD
- (22) - 領域模型
- (23) - 領域建模三字經
- (24) - 設計模型
- (25) - 類模型
- (26) - 類模型三板斧
- (27) - 動態模型設計
- (28) - 設計原則:內聚&耦合
- (29) - 高內聚低耦合
- (30) - SRP原則
- (31) - OCP原則
- (32) - LSP原則
- (33) - ISP原則
- (34) - DIP原則
- (35) - NOP原則
- (36) - 設計原則如何用?
- (37) - 設計模式:瑞士軍刀 or 錘子?
- (38) - 設計模式之道
- (39) - 設計原則 vs 設計模式
- (40) - DECORATOR模式
- (完)- 書籍已經出版