开闭原则是面向对象的可复用设计的第一块基石,它是最重要的面向对象设计原则。开闭原则由Bertrand  Meyer于1988年提出,其定义如下:

开闭原则(Open-Closed Principle, OCP):一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。

在开闭原则的定义中,软件实体可以指一个软件模块、一个由多个类组成的局部结构或一个独立的类。

任何软件都需要面临一个很重要的问题,即它们的需求会随时间的推移而发生变化。当软件系统需要面对新的需求时,我们应该尽量保证系统的设计框架是稳定的。如果一个软件设计符合开闭原则,那么可以非常方便地对系统进行扩展,而且在扩展时无须修改现有代码,使得软件系统在拥有适应性和灵活性的同时具备较好的稳定性和延续性。随着软件规模越来越大,软件寿命越来越长,软件维护成本越来越高,设计满足开闭原则的软件系统也变得越来越重要。

为了满足开闭原则,需要对系统进行抽象化设计,抽象化是开闭原则的关键。在Java、C#等编程语言中,可以为系统定义一个相对稳定的抽象层,而将不同的实现行为移至具体的实现层中完成。在很多面向对象编程语言中都提供了接口、抽象类等机制,可以通过它们定义系统的抽象层,再通过具体类来进行扩展。如果需要修改系统的行为,无须对抽象层进行任何改动,只需要增加新的具体类来实现新的业务功能即可,实现在不修改已有代码的基础上扩展系统的功能,达到开闭原则的要求。

Sunny软件公司开发的CRM系统可以显示各种类型的图表,如饼状图和柱状图等,为了支持多种图表显示方式,原始设计方案如图1所示:

图1 初始设计方案结构图

在ChartDisplay类的display()方法中存在如下代码片段:

......
if (type.equals("pie")) {
PieChart chart = new PieChart();
chart.display();
}
else if (type.equals("bar")) {
BarChart chart = new BarChart();
chart.display();
}
......
      在该代码中,如果需要增加一个新的图表类,如折线图LineChart,则需要修改ChartDisplay类的display()方法的源代码,增加新的判断逻辑,违反了开闭原则。

现对该系统进行重构,使之符合开闭原则。

在本实例中,由于在ChartDisplay类的display()方法中针对每一个图表类编程,因此增加新的图表类不得不修改源代码。可以通过抽象化的方式对系统进行重构,使之增加新的图表类时无须修改源代码,满足开闭原则。具体做法如下:

(1) 增加一个抽象图表类AbstractChart,将各种具体图表类作为其子类;

(2)  ChartDisplay类针对抽象图表类进行编程,由客户端来决定使用哪种具体图表。

重构后结构如图2所示:

图2 重构后的结构图

在图2中,我们引入了抽象图表类AbstractChart,且ChartDisplay针对抽象图表类进行编程,并通过setChart()方法由客户端来设置实例化的具体图表对象,在ChartDisplay的display()方法中调用chart对象的display()方法显示图表。如果需要增加一种新的图表,如折线图LineChart,只需要将LineChart也作为AbstractChart的子类,在客户端向ChartDisplay中注入一个LineChart对象即可,无须修改现有类库的源代码。

注意:因为xml和properties等格式的配置文件是纯文本文件,可以直接通过VI编辑器或记事本进行编辑,且无须编译,因此在软件开发中,一般不把对配置文件的修改认为是对系统源代码的修改。如果一个系统在扩展时只涉及到修改配置文件,而原有的Java代码或C#代码没有做任何修改,该系统即可认为是一个符合开闭原则的系统。
 ———————————————— 
版权声明:本文为CSDN博主「Liuwei-Sunny」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lovelion/article/details/7537584

设计模式---开闭原则相关推荐

  1. 设计模式-开闭原则(6)

    设计原则 单一职责原则 里氏替换原则 依赖倒置原则 接口隔离原则 迪米特法则 开闭原则 开闭原则 开闭原则是Java世界里最基础的设计原则, 它指导我们如何建立一个稳定的. 灵活的系统, 先来看开闭原 ...

  2. 23种设计模式-开闭原则

    概念: 1) 开闭原则(Open Closed Principle)是编程中最基础.最重要的设计原则 2) 一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方).用抽象构建框 ...

  3. Java设计模式-开闭原则

    总原则:开闭原则(Open Close Principle)   定义:一个软件实体如类.模块和函数应该对扩展开放,对修改关闭.   问题由来:在软件的生命周期内,因为变化.升级和维护等原因需要对软件 ...

  4. 图解Java设计模式-开闭原则

    开闭原则是编程中最基础,最重要的设计原则 一个软件实体如类,模块和函数应该对外开放(对提供方),对修改关闭(对使用方).用抽象构建框架,用实现扩展细节 当软件需要变化时,尽量通过扩展软件实体的行为来实 ...

  5. Java设计模式——开闭原则(实例)

    1.基本介绍 开闭原则是编程中最基础.最重要的设计原则 一个软件实体,如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方).用抽象构建框架,用实现扩展细节. 当软件需要变化时,尽量通过扩 ...

  6. [设计模式]开闭原则

    开闭原则: 对扩展开放,对修改关闭. 增加功能是提过增加代码来实现的,而不是去修改源代码. 代码如下: #include <iostream> #include <string> ...

  7. 设计模式——开闭原则

    开闭原则:对扩展开放,对修改关闭. 具体实现:为系统定义一个相对稳定的抽象层,而将不同的实现行为移至具体的实现层中完成.在很多面向对象编程语言中都提供了接口.抽象类等机制,可以通过它们定义系统的抽象层 ...

  8. 设计模式-开闭原则(OCP)

    开闭原则(open closed principle) 目标:已有的场景下,对于需要拓展的进行开放,拒绝直接的功能修改 需求: 吃鸡游戏要高亮 + LOL需要弹出折扣 // sprint1 - 青年节 ...

  9. 设计模式开闭原则--java

    静态工厂模式 + 反射控制入参范围 public interface IPrinter {void print(); }public class CanonPrinter implements IPr ...

最新文章

  1. access设计视图打不开_定制橱柜衣柜怎么测量才能避免出错?(设计师必看)
  2. windows 7 网卡物理地址修改方法
  3. php中get_featured_posts()是什么意思,php – 在WP_Query中获取WooCommerce特色产品
  4. node 调用腾讯大数据接口
  5. 管理系统中计算机应用怎么自学,有自学的没,管理系统中计算机应用上机题。...
  6. javascript计算小数保留两位小数,多位小数的方法
  7. linux设置板卡时间,嵌入式VS-RK3288板卡 Linux 修改BOOTDELAY介绍
  8. 外部导入方式添加背景图_web前端基础:CSS的三种导入方式说明
  9. tenda 服务器无法打开网页,Win7系统网页打不开qq能上怎么办? | 192路由网
  10. PollingBlockTracker - encountered an error while attempting to update latest block:
  11. 超启发式算法(hyper heuristic)
  12. c语言如何使用floor函数,floor函数 Excel中floor函数怎么使用
  13. 类和对象8:数值方法
  14. 京东快递查询延误物流信息的方法
  15. 学会这些方法,扩展磁盘分区还不是轻轻松松?
  16. 关于RPC框架封装时ThreadPool的选型和设计
  17. YJJ's Salesman HDU - 6447(线段树 单点更新+DP思想)
  18. GICv3软件overview手册之GICv3基本功能(3)
  19. 在cmd 中输入了错误mysql命令后,如何退出?
  20. c语言课后答案上海交通,上海交通大学继续教育学院2012春——程序设计(C)作业1(有答案)...

热门文章

  1. STM32_ADC初始化参数说明以及常用的固件库
  2. linux路由内核实现分析(四)---路由缓存机制(3)
  3. 从程序员到项目经理(三)
  4. c语言试题c组卡片换位,蓝桥杯 卡片换位 - 李韬|aitom|机器人|SLAM - OSCHINA - 中文开源技术交流社区...
  5. mysql 报错从 新安装
  6. [JSON].getObj( keyPath )
  7. CentOS下安装jdk1.8.0_181
  8. 小明滚出---响应对象HttpServletResponse和请求对象HttpServletRequest实例
  9. 十进制与二进制之间的转换
  10. 【转】linux /centos 中OpenSSL升级方法详解