## 连载:面向对象葵花宝典:思想、技巧与实践(31) - OCP原则
开闭原则是一个大部分人都知道,但大部分人都不懂的设计原则!![](https://box.kancloud.cn/2016-01-20_569f5ccae167f.gif)
====================================================================
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模式
- (完)- 书籍已经出版