2015-04-13 06:30:01

阅读( 137 )

开闭原则的解释就是:软件实体应当对扩展开放,对修改关闭,也就是:软件系统中包含的各种组件,例如模块(Modules)、类(Classes)以及功能(Functions)等等,应该在不修改现有代码的基础上,引入新功能。开闭原则中“开”,是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的;开闭原则中“闭”,是指对于原有代码的修改是封闭的,即不应该修改原有的代码。

开闭原则是说我们应该努力设计不需要修改的模块。在扩展系统的行为时,我们只需要添加新的代码,而不需要修改已有的代码。一般可以通过添加新的子类和重写父类的方法来实现。

满足开闭原则的模块需要符合如面两个标准:

对扩展开放 ——- 模块的行为可以被扩展从而满足新的需求。

对修改关闭 ——- 不需要修改模块的源代码。(或者尽量使修改最小化)

怎样实现开闭原则

抽象

多态

继承

接口

要想使一个软件系统的所有模块都满足开闭原则是不太现实的,不过我们应该努力使大部分模块满足开闭原则。开闭原则是面向对象设计的核心,满足该原则可以达到最大限度的复用和可维护性。

实例

考虑下面某个类的方法:

Java代码

public double totalPrice(Part[] parts) {

double total = 0.0;

for (int i=0; i

total += parts.getPrice();

}

return total;

}

上面函数的功能是计算给定的零件数组中所有零件价格的总和,如果Part是一个基类或者接口,那我们就可以利用多态的特性,当有新的零件被添加进来时不需要修改该函数的代码。这样它就可以满足开闭原则。

但是如果我们的会计部门规定当计算主板和内存的价格时,需要添加一些额外的费用,请看下面的代码:

Java代码

public double totalPrice(Part[] parts) {

double total = 0.0;

for (int i=0; i

if (parts instanceof Motherboard)

total += (1.45 * parts.getPrice());

else if (parts instanceof Memory)

total += (1.27 * parts.getPrice());

else

total += parts.getPrice();

}

return total;

}

现在它还符合开闭原则吗?不!每次会计部门发布一个新的价格政策时,我们都需要修改totalPrice()方法!它对修改不是关闭的,显然,价格政策的改变意味着我们必须修改某处的代码,那么我们应该怎么做呢?为了使用我们第一个版本的totalPrice()方法,我们需要把Part的 getPrice()方法的价格政策包含进来。

下面是Part和ConcretePrat类:

Java代码

// Class Part is the superclass for all parts.

public class Part {

private double price;

public Part(double price) (this.price = price;}

public void setPrice(double price) {this.price = price;}

public double getPrice() {return price;}

}

// Class ConcretePart implements a part for sale.

// Pricing policy explicit here!

public class ConcretePart extends Part {

public double getPrice() {

// return (1.45 * price); //Premium

return (0.90 * price); //Labor Day Sale

}

}

但是,现在如果价格政策改变,我们必须修改Part的子类,一个更好的方法是建立一个PricePolicy类,它可以为我们提供不同的价格政策:

Java代码

/**

* Class PricePolicy implements a given price policy.

*/

public class PricePolicy {

private double factor;

public PricePolicy (double factor) {

this.factor = factor;

}

public double getPrice(double price) {return price * factor;}

}

使用这种方法,我们可以在运行时动态的设置Part对象所引用的PricePoilcy对象,在实际的程序中,零件的价格和相关的PricePolicy可以从数据库中获取。

总结

像许多其他原则一样,开闭原则只是面向对象设计的一个原则,实现一个灵活的设计需要额外的时间和努力,引入新的抽象层会增加代码的复杂性。因此,该原则适用于那些需求会经常发生变化的系统。有许多设计模式可以帮助我们扩展功能而不需要修改代码。例如,装饰模式等。

分享给朋友:

亲~ 如果您有更好的答案 可在评论区发表您独到的见解。

您想查看更多的信息:

面试题

java开闭原则_什么是开闭原则?如何实现开闭原则相关推荐

  1. 我的世界中国版java版不更新_我的世界中国版PCJava版开测 正版玩家回归奖励公布...

    欢迎冒险家回归 家族盛典福利不断<我的世界>中国版PC Java版不限号测试的开启,意味着回家的大门已经向所有玩家敞开.中国版大家庭也为回归的冒险家准备了丰富的活动和福利.所有8日当天回归 ...

  2. java山海经之轩辕_轩辕传奇手游山海经任务:盘古开天之遂古之初

    <山海经>剧情副本作为轩辕勇士关注度最高的副本,不仅因为我们的游戏本身就是以山海经为背景,还因为这个剧情副本带给大家不一样的游戏体验,同时,还可以收获卡牌提升战力.但是很多小伙伴会卡在一些 ...

  3. 自学JAVA成了自闭症_他把三年才学会上厕所的自闭症儿子,教育成全年级第一...

    社会上有这么一群人,总是被大家忽略或忘记的存在,他们就是"来自星星的孩子",据说他们来自遥远的外星,事实上的意义是指他们的世界离我们很遥远,而我们的世界又是他们所不能理解的. &q ...

  4. 联想st510开卡软件_固态硬盘修复(慧荣sm2246XT主控开卡教程)

    本帖最后由 lwj2996868501 于 2019-3-25 13:12 编辑 此教程仅适用于固态硬盘且主控SM2246XT的,不是这个主控的就没必要看下去了! 准备工具:起子,镊子(铁丝也行),坏 ...

  5. 山东泰开集团 工业机器人_对接世界“工业4.0”泰开机器人 大步向智能制造领域拓展延伸...

    原标题:对接世界"工业4.0"泰开机器人 大步向智能制造领域拓展延伸 人民网泰安6月26日电 6月26日"聚焦泰安看发展"2019全国网络媒体泰安行采访团记者来 ...

  6. 里氏替换原则_春辉带你了解面相对象设计第二原则(里氏替换原则)

    里氏替换原则的定义 里氏替换原则(Liskov Substitution Principle,LSP)由麻省理工学院计算机科学实验室的里斯科夫(Liskov)女士在 1987 年的"面向对象 ...

  7. smart原则_为什么现在少有人用德鲁克的SMART原则做目标管理了?

    互联网平台充斥了各类成功学文章,但大多数鸡汤文只谈坚持,不谈策略.王健林定下一个亿的小目标被网友编成了各种段子,却极少有人去探究他实现目标的过程,用的什么方法.从企业规模来看,我们没有理由说王健林定下 ...

  8. MATLAB_4-形态学_腐蚀_膨胀_灰度图的腐蚀以及膨胀_开运算_闭运算_文章末尾有几个素材例子

    素材链接: MATLAB_4-形态学_课程需要的素材 记住单词拼写: 腐蚀 erode 膨胀 dilate 开运算 open 闭运算 close 图像重建 imreconstruct reconstr ...

  9. java solid设计原则_六大设计原则之里氏替换原则(LSP)

    一.SOLID 设计模式的六大原则有: Single Responsibility Principle:单一职责原则 Open Closed Principle:开闭原则 Liskov Substit ...

  10. 单片机程序配置成开漏输出_单片机I/O开漏输出详解

    开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内). 我们先来说说集电极开路输出的结构.集电极开路输出的结构如 ...

最新文章

  1. PE文件结构及其加载机制(三)
  2. 搜索引擎爬虫蜘蛛的UserAgent收集
  3. tensorflow tf.train.ExponentialMovingAverage() (滑动平均模型)(移动平均法 Moving average,MA)(用于平滑数据波动对预测结果的影响)
  4. python调用r语言_【Python调用第三方R包】【环境变量设置】Python 通过rpy2调用 R语言...
  5. 使计算机工作必不可缺的软件,探讨测绘工程中计算机制图的运用问题(原稿)
  6. Topcoder SRM 630div 2
  7. POJ 3181 Dollar Dayz DP
  8. php quick,Gitee 极速下载
  9. mysql ascii ord_MySQL ORD()函数使用实例介绍
  10. php mysql 获取排名,Mysql排序获取排名的实例代码
  11. 怎么计算算法复杂度 big O
  12. vim 编辑器常用命令
  13. 管家婆打印报错——进程无法访问
  14. 关于urule决策引擎客户端服务器配置的一些细节
  15. Matlab imcrop 与 opencv ROI
  16. PyTorch实例:用ResNet进行交通标志分类
  17. 小觅双目+IMU联合标定
  18. ARP断网攻击(详细教程)
  19. UVA 10004 Bicoloring (二分染色)
  20. Origin与OriginPro 版本一览图

热门文章

  1. python3中datetime库,time库以及pandas中的时间函数区别与详解
  2. 【老生谈算法】matlab实现K-means算法源码——K-means算法
  3. ZigBee转包、Ubiqua抓包工具的安装教程附带ZigBee抓包使用和入网流程解析
  4. eCryptfs,文件系统级加密,在登出时自动为文件加密。通过挂载文件解密和卸载文件加密的方式保护文件
  5. JS常用方法模板(更新中)
  6. 一些常见的伪类选择器
  7. 牛客网sql题详解21-30
  8. 奥数 python_Python 和 奥数 — 周期问题
  9. 铂诺董事长简毅对话AI大咖:AI与人类灵性结合将诞生新智慧
  10. 市政单轴搅拌桩施工记录--深层搅拌桩施工记录