面向对象设计原则之开闭原则
两截门--一个被水平分割为两部分的门,这样每一部分都可以独立保持开放或封闭
开放-封闭原则(The Open-Closed Principle)
软件实体(类、模块、函数)应该是可以扩展的,但是不可以修改的。
如果程序中的一处改动就会产生连锁反应,导致一系列的相关模块的改动,那么设计就具有僵化的臭味。如果正确的应用OCP,那么以后再进行同样的改动时,就只需要添加新的代码,而不必改动已经正常运行的代码。
描述
主要两个特征:
- “对于扩展是开放的”
模块的行为是可以扩展的,当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。简言之,我们可以改变模块的功能。 - “对于更改是封闭的”
对模块进行扩展时,不必改动模块的源代码。
关键是抽象
下图展示了一个简单的不遵循OCP的设计。Client类和Server类都是具体类,Client类使用Server类。如果我们希望Client对象使用另外一个不同的服务器对象,那么就必须要把Client类中使用Server类的地方更改为新的服务器类
下图是根据OCP设计重构的设计
ClientInterface类是一个拥有抽象成员函数的抽象类,Client类使用这个抽象类。如果我们希望Client对象使用一个不同的服务器类,那么只需要冲ClientInterface类派生一个新的类,无需对Client类做任何改动。
Shape应用程序
应用程序中有Circle、Square列表,需求是:绘制他们
从OCP原则考虑,设计方案如下,
class Shape{
draw();
}class Circle extends Shape{draw(){}
}class Square extends Shape{draw(){}
}Class DrawAllShape{void drawAllShapes(List<Shape> lists){for(Shape shape :lists){shape.draw();}}
}
根据此设计,如果新增一个Triangle类,只需新增代码即可,无需改动上述代码,达到了开闭原则。真的吗???
并非100%封闭
如果需求要求所有圆必须在正方形之前绘制,那么DrawAllShape无法对这种变化做到封闭。要实现这个需求,我们需要修改DrawAllShape,使它首先扫描列表中的圆,然后在扫描所有的正方形。
预测变化和贴切的结构
一般来说,无论模块是多么封闭,都会存在一些无法对之封闭的变化,没有对于所有的情况都贴切的模型。
既然不能完全封闭,就要有策略的对待这个问题,设计人员必须对于他设计的模块应该对哪种变化封闭作出选择,他必须先猜测出最有可能发生的变化种类,然后构造抽象来隔离那些变化。这需要设计人员具备一些从经验中获得的预测能力。
遵循OCP的代价是昂贵的,创建正确的抽象是要花费开发时间和精力的,同时,那些抽象也增加了软件设计的复杂性,开发人员有能力处理的抽象的数量也是有限的,显然,我们希望把OCP的应用限定在可能会发生的变化上。
- 只受一次愚弄
最初编写代码的时候,假设变化不会发生,当变化发生了,我们就创建抽象来隔离以后发生的同类变化。 - 刺激变化
尽早查明可能发生的变化,尽早接受变化带来的改变。
Shape改造
class Shape{draw();//precedes();precedes(OrderRule order){}
}
Class DrawAllShape{sort(list);void drawAllShapes(List<Shape> lists){for(Shape shape :lists){shape.draw();}}
}
precedes()考虑到枚举排序的话违背了OCP,可以将规则定义起来,改造成precedes(OrderRule order),排序规则从OrderRule中读取,此时对与Shape绘制顺序的变化不封闭的唯一部分就是OrderRule。
结论
在许多方面,OCP都是面向对象设计的核心所在。遵循这个原则可以的带来面向对象技术所声称的巨大好处(灵活性,可重用性,可维护性)。对于应用程序中的每个部分都肆意的进行抽象同样不是一个好主意。正确的做法是,开发人员应该仅仅对程序中呈现出频繁变化的那些部分做出抽象。拒绝不成熟的抽象和抽象本身一样重要。
转载于:https://www.cnblogs.com/vincent0928/p/6568354.html
面向对象设计原则之开闭原则相关推荐
- Java面向对象设计原则1——开闭原则
在我们学习面向对象编程的时候,总会出现一些问题,好比以前刚刚写好的代码,上线测试可以.正常运行,突然有一天说要加一个功能,改完之后,发现以前正常运行的功能不能用了,类似这样的问题有好多好多,为了避免类 ...
- 6大设计原则之开闭原则
开闭原则的定义 开闭原则的定义: 一个软件实体,如类.模块和函数应该对扩展开放,对修改关闭.即一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化. 软件实体包括一下部分 项目或软件 ...
- Java设计原则之单一职责原则、开闭原则、里氏代换原则
文章目录 面向对象设计原则概述 单一职责原则 开闭原则 里氏代换原则 面向对象设计原则概述 软件的可维护性(Maintainability)和可复用性(Reusability)是两个非常重要的用于衡量 ...
- 设计原则:开闭原则(OCP)
1.什么是开闭原则 开闭原则的英文是Open Closed Principle,缩写就是OCP.其定义如下: 软件实体(模块.类.方法等)应该"对扩展开放.对修改关闭". 从定义上 ...
- 设计模式-02.经典设计原则-第一节-单一职责原则,开闭原则,里式替换,接口隔离【万字长文系列】
文章目录 设计模式经典设计原则-第一节 单一职责原则(SRP) 如何理解单一职责原则? 如何判断类的职责是否足够单一? 类的职责是否设计得越单一越好? 开闭原则(OCP) 如何理解"对扩展开 ...
- 关于Java面向对象程序设计原则之一——开闭原则的思考与分享
整理日期:2022-05-27 目录 一.开闭原则 二.为什么使用开闭原则 三.如何在程序设计中体现开闭原则 一.开闭原则 开闭原则(Open-Closed Principle, OCP)是指一个软件 ...
- [设计原则] 六大设计原则之“开闭原则”
[设计原则] 六大设计原则之"开闭原则" 目录 [设计原则] 六大设计原则之"开闭原则" 什么是开闭原则 为什么使用开闭原则 如何使用开闭原则 注意事项 总结 ...
- 设计模式-软件架构设计七大原则及开闭原则详解
前言 在日常工作中,我们使用Java语言进行业务开发的时候,或多或少的都会涉及到设计模式,而运用好设计模式对于我而言,又是一个比较大的难题.为了解决.克服这个难题,Remi酱特别开了这个博客来记录自己 ...
- 七大设计原则之开闭原则
一.开闭原则介绍 开闭原则(Open Closed Principle)是编程中最基础,也是最重要的设计原则.编程中遵循其他原则以及使用设计模式的目的就是遵循开闭原则. 一个软件实体如类,模块和函数应 ...
- 设计模式六大原则之--开闭原则(OCP)
设计模式六大原则之--开闭原则(OCP) 前言 1 描述 2 理解: 3 问题由来: 4 使用LoD的好处: 5 难点: 6 最佳实践: 7 范例: 前言 The Open - Closed Prin ...
最新文章
- 华为消息推送 有透传通道吗_华为首款头戴耳机FreeBuds Studio正式发布,能否撑起品牌之名?...
- 不关闭seLinux解决vsftpd服务本地用户不能登录问题(500 OOPS: cannot change directory:/home/***
- SCSF 系列:Smart Client Software Factory 启动过程详解
- bzoj1095: [ZJOI2007]Hide 捉迷藏 动态点分治学习
- How to tell if UIViewController's view is visible
- 有向图的拓扑排序的理解和简单实现(Java)
- 基于小波变换的图像压缩解压缩仿真
- 《系统集成项目管理工程师》必背100个知识点-31WBS的分解原则
- [Android]关于IntentService
- 原生JS字符串操作方法汇总
- 430单片机实现三人投票表决器_长虹KFR-28变频空调器室内机控制板电路原理分析...
- 拉拢苹果用户,谷歌推出“从 iOS 转移到 Android” App
- Python Seaborn教程
- Struts2 - 常用的constant总结
- 人工智能——前言概述
- linux能安装cad快速看图不,ubuntu下能过wine安装cad快速看图
- 如何自己搭建测试环境
- NFT交易平台2.0来了,源代码,智能合约整套
- CSS 使文字纵向排列的七种方
- CRMEB在线教育知识付费系统应用领域及功能介绍