java开闭原则_什么是开闭原则?如何实现开闭原则
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开闭原则_什么是开闭原则?如何实现开闭原则相关推荐
- 我的世界中国版java版不更新_我的世界中国版PCJava版开测 正版玩家回归奖励公布...
欢迎冒险家回归 家族盛典福利不断<我的世界>中国版PC Java版不限号测试的开启,意味着回家的大门已经向所有玩家敞开.中国版大家庭也为回归的冒险家准备了丰富的活动和福利.所有8日当天回归 ...
- java山海经之轩辕_轩辕传奇手游山海经任务:盘古开天之遂古之初
<山海经>剧情副本作为轩辕勇士关注度最高的副本,不仅因为我们的游戏本身就是以山海经为背景,还因为这个剧情副本带给大家不一样的游戏体验,同时,还可以收获卡牌提升战力.但是很多小伙伴会卡在一些 ...
- 自学JAVA成了自闭症_他把三年才学会上厕所的自闭症儿子,教育成全年级第一...
社会上有这么一群人,总是被大家忽略或忘记的存在,他们就是"来自星星的孩子",据说他们来自遥远的外星,事实上的意义是指他们的世界离我们很遥远,而我们的世界又是他们所不能理解的. &q ...
- 联想st510开卡软件_固态硬盘修复(慧荣sm2246XT主控开卡教程)
本帖最后由 lwj2996868501 于 2019-3-25 13:12 编辑 此教程仅适用于固态硬盘且主控SM2246XT的,不是这个主控的就没必要看下去了! 准备工具:起子,镊子(铁丝也行),坏 ...
- 山东泰开集团 工业机器人_对接世界“工业4.0”泰开机器人 大步向智能制造领域拓展延伸...
原标题:对接世界"工业4.0"泰开机器人 大步向智能制造领域拓展延伸 人民网泰安6月26日电 6月26日"聚焦泰安看发展"2019全国网络媒体泰安行采访团记者来 ...
- 里氏替换原则_春辉带你了解面相对象设计第二原则(里氏替换原则)
里氏替换原则的定义 里氏替换原则(Liskov Substitution Principle,LSP)由麻省理工学院计算机科学实验室的里斯科夫(Liskov)女士在 1987 年的"面向对象 ...
- smart原则_为什么现在少有人用德鲁克的SMART原则做目标管理了?
互联网平台充斥了各类成功学文章,但大多数鸡汤文只谈坚持,不谈策略.王健林定下一个亿的小目标被网友编成了各种段子,却极少有人去探究他实现目标的过程,用的什么方法.从企业规模来看,我们没有理由说王健林定下 ...
- MATLAB_4-形态学_腐蚀_膨胀_灰度图的腐蚀以及膨胀_开运算_闭运算_文章末尾有几个素材例子
素材链接: MATLAB_4-形态学_课程需要的素材 记住单词拼写: 腐蚀 erode 膨胀 dilate 开运算 open 闭运算 close 图像重建 imreconstruct reconstr ...
- java solid设计原则_六大设计原则之里氏替换原则(LSP)
一.SOLID 设计模式的六大原则有: Single Responsibility Principle:单一职责原则 Open Closed Principle:开闭原则 Liskov Substit ...
- 单片机程序配置成开漏输出_单片机I/O开漏输出详解
开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内). 我们先来说说集电极开路输出的结构.集电极开路输出的结构如 ...
最新文章
- PE文件结构及其加载机制(三)
- 搜索引擎爬虫蜘蛛的UserAgent收集
- tensorflow tf.train.ExponentialMovingAverage() (滑动平均模型)(移动平均法 Moving average,MA)(用于平滑数据波动对预测结果的影响)
- python调用r语言_【Python调用第三方R包】【环境变量设置】Python 通过rpy2调用 R语言...
- 使计算机工作必不可缺的软件,探讨测绘工程中计算机制图的运用问题(原稿)
- Topcoder SRM 630div 2
- POJ 3181 Dollar Dayz DP
- php quick,Gitee 极速下载
- mysql ascii ord_MySQL ORD()函数使用实例介绍
- php mysql 获取排名,Mysql排序获取排名的实例代码
- 怎么计算算法复杂度 big O
- vim 编辑器常用命令
- 管家婆打印报错——进程无法访问
- 关于urule决策引擎客户端服务器配置的一些细节
- Matlab imcrop 与 opencv ROI
- PyTorch实例:用ResNet进行交通标志分类
- 小觅双目+IMU联合标定
- ARP断网攻击(详细教程)
- UVA 10004 Bicoloring (二分染色)
- Origin与OriginPro 版本一览图
热门文章
- python3中datetime库,time库以及pandas中的时间函数区别与详解
- 【老生谈算法】matlab实现K-means算法源码——K-means算法
- ZigBee转包、Ubiqua抓包工具的安装教程附带ZigBee抓包使用和入网流程解析
- eCryptfs,文件系统级加密,在登出时自动为文件加密。通过挂载文件解密和卸载文件加密的方式保护文件
- JS常用方法模板(更新中)
- 一些常见的伪类选择器
- 牛客网sql题详解21-30
- 奥数 python_Python 和 奥数 — 周期问题
- 铂诺董事长简毅对话AI大咖:AI与人类灵性结合将诞生新智慧
- 市政单轴搅拌桩施工记录--深层搅拌桩施工记录