连载:面向对象葵花宝典:思想、技巧与实践(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
================================================ 

时间: 2024-09-15 00:24:35

连载:面向对象葵花宝典:思想、技巧与实践(31) - OCP原则的相关文章

连载:面向对象葵花宝典:思想、技巧与实践(28) - 设计原则:内聚&耦合

前面通过实例讲解了一个一环扣一环的面向对象的开发流程:用例模型 -> 领域模型 -> 设计模型(类模型 + 动态模型),解答了面向对象如何做的问题.接下来我们就要讲"如何做好面向对象设计"的技巧了 =================================================================== [内聚] 参考维基百科的解释,内聚的含义如下: cohesion refers to the degree to which the eleme

连载:面向对象葵花宝典:思想、技巧与实践(1) - 程序设计思想的发展

史前时代:面向机器 最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行的指令和数据.简单来说,就是直接编写0和1的序列来代表程序语言.例如:使用0000 代表 加载(LOAD),0001 代表 存储(STORE)等.  机器语言由机器直接执行,速度快,但一个很明显的缺点就是:写起来实在是太困难了,一旦你发现自己写错了,改起来更蛋疼!这样直接导致程序编写效率十分低下,编写程序花费的时间往往是实际运行时间的几十倍或几百倍.  有一个关于机器语言和比尔盖茨的笑话,是说比尔

连载:面向对象葵花宝典:思想、技巧与实践(36) - 设计原则如何用?

经过前面深入的阐述,SOLID的原则我们已经基本上讲清楚了,但如果想熟练的应用SOLID原则,仅仅知道SOLID是什么(what)还不够,我们还需要知道SOLID原则在什么时候和什么场景应用(when或where).   幸运的是,SOLID原则的5个独立原则在实际应用中基本上都是独挡一面,并不会在某个地方需要同时从可选的几个原则中挑选一个最优的原则来应用,这样大大降低了我们应用SOLID原则的难度.   SOLID原则具体的应用场景如下: SRP原则:用于类的设计 当我们想出一个类,或者设计出

013_《Delphi面向对象编程思想》

<Delphi面向对象编程思想> Delphi 教程 系列书籍 (013) <Delphi面向对象编程思想> 网友(邦)整理 EMail: shuaihj@163.com 下载地址: Pdf 作者: 刘艺 [作译者介绍] 丛书名: Borland核心技术丛书 出版社:机械工业出版社 ISBN:7111127722 上架时间:2003-10-10 出版日期:2003 年9月 开本:16开 页码:476 版次:1-1 内容简介 这是一本纯粹讨论dlephi面向对象编程的力作. 本书以精

Silverlight游戏设计:(五)面向对象的思想塑造游戏对象

传说,面向对象的开发模式最初是因为程序员偷懒而不小心诞生的.发展至今,人们从最初的热忠于 讨论某某语言是否足够面向对象到现在开始更广泛的关注面向对象的思想而不是具体内容.面向对象的思 想其实并不深奥,它存在的目的只有一个:让程序开发更贴近我们的现实世界. 还记得猫.猫叫:狗.狗吃东西吗?无数的程序员都喜欢将此类似的情形设计当作面向对象最好的例 子.是的,非常生动且形象:但实际运用中你是否能真正做到举一反三? 回述到游戏设计中,大家是否时常会感觉游戏世界与我们的真实世界如此贴近?游戏中的精灵好比我

java语言学习002_面向对象编程思想

      人类在认识世界时,为了方便自己和智慧提升,很自然的对事物进行了分类.对世界进行了抽象,若把所有各个事物看做对象,纵观所有对象,这些对象具有各自的或共有的特征,并且又有共有的或各自的的能力,这样就可以对具有相同一些特征和一些能力的事物进行了归类.       比如,车,有汽车,火车他们都有哪些属性?                  汽车,特征:长度,颜色,速度,轮胎,载重,平面行走--能力:移动,载东西,--                  火车,特征:长度,颜色,速度,轮胎,载重

求助、面向对象的思想查找字符串中的数字

问题描述 要用面向对象的思想来查找字符串中的数字.实现判断某个字符是否位数字的方法如下:publicstaticboolgetNumeric(stringstr){boolb=false;string[]ArrayInt=newstring[]{"1","2","3","4","5","6","7","8","9","

将面向对象的思想带入TC

写TC貌似是很简单的工作,但当动手写的时候往往会出现,不知道写什么,又感觉有一堆的东西需要写,即使一个简单的日常也会觉得里面的逻辑非常复杂,然后就是晕得不知所向. 个人认为,写TC没有固定的模式,也没有唯一的答案,每个人的方式不同,习惯不同,TC中的如何分类归纳也就自然不相同.但目标是一致的,基本目标是覆盖需求.无盲区:加强目标是加深测试点,完善用户友好性等. 下面分享下我写TC的几种思路. 第一种思路--先对象,后流程 面向对象是在平常入门学习中 首先接触到的概念,它不仅仅存在于代码的编写中,

重温面向对象的思想——构造器和重载

1.this关键字 this表示这个对象的参考名称:例如this.age1=age2;表示将age2的值,赋值给这个对象的私有属性age1. 2. .重温面向对象的思想--构造器和重载 构造器:创建一个对象时,有时候需要对在实例化一个对象时,对这个对象进行初始化,这个时候我们就需要构造方法来进行这种初始化. 重载:当这种初始化需要按照不同的语境,不同的参数的构造器来进行初始化. 总结--方法的重载是多种构造器,用以完成不同的初始化. -注意:构造器==构造方法,两者一样 3.构造方法和自定义方法