原文:https://blog.csdn.net/tjiyu/article/details/57079927

面向对象设计原则(二):开放-封闭原则(OCP)

开放-封闭原则(Open-closed principle,OCP)也称开闭原则,是面向对象设计(OOD)中比较重要、常见的一种,下面来总结开放-封闭原则的知识点,包括:

1、什么是开放-封闭原则?

2、为什么需要遵守开放-封闭原则?

3、怎么做到开放-封闭原则?

4、开放-封闭原则需要注意什么?

1、什么是开放-封闭原则(OCP)
1-1、原则的定义
       开放-封闭原则(Open-closedprinciple,OCP)可以表示为:

软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改的。

1-2、两个主要的特征
       遵循开放-封闭原则设计出的模块具有两个主要的特征,如下:

1、对于扩展是开放的(open for extension)

这意味着模块的行为是可以扩展的。

当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。

换句话说,我们可以改变模块的功能。

2、对于修改是封闭的(closed for modification)

对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。

模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动。

2、为什么需要开放-封闭原则
2-1、开放-封闭原则能带来什么?
       可以从下面的一些问题来描述:

怎么样的设计才能面对需求的改变却可以保持相对稳定,从而使得系统可以在第一版本以后不断推出新的版本呢?

怎样可能在不改动模块源代码的情况下去更改它的行为呢?

如果不改变一个模块,又怎么能够去改变它的功能呢?

bertrand meyer 在1988年提出的著名的开放—封闭原则(the open-closed princle)为我们提供了指引。

在许多方面,开放-封闭原则都是面向对象设计的核心所在,遵循这个原则可以带来面向对象技术所声称的巨大好处:灵活性、可重用性以及灵活性。

2-2、违反开放-封闭原则有什么坏处?
       违反开放-封闭原则的程序中,通常一处改动就会产生连锁反应,导致一系列相关模块的改动,那么设计就具有僵化性。

OCP建议我们应该对系统进行重构,这样以后对系统再进行这样那样的改动时,就不会导致更多的修改。

如果正确地应用OCP,那么以后再进行同样的改动时,就只需要添加新的代码,而不必改动已经正常运行的代码。

3、怎么做到开放-封闭原则
3-1、抽象是关键
      由于模块依赖于一个固定的抽象体,所以它对于更改可以是封闭的。

同时,通过从这个抽象体派生,也可以扩展此模块的行为。

3-2、应用开放-封闭原则的两种方法
      对于类来说,开始OCP依赖于面向对象继承(特别是实现继承)的概念;

而后来,开放/封闭原理被重新定义使用抽象接口,其中可以改变实现,还可以创建多个实现,并且彼此多态地替换。

即可以有两种方法应用OCP:

1、从抽象类继承

最简单的方法是在继承原始类实现的新派生(子)类上实现新的功能。

2、实现抽象接口

另一种方法是使用抽象接口来调解客户端对原始类的访问,因此可以通过同一接口访问的新类实现新功能。

两种方法都可以创建新类,并保持原始实现不变,但提倡的是第二种。

4、开放-封闭原则需要注意什么
4-1、无法做到100%的封闭
      无论模块是多么的"封闭",都会存在一些无法对之封闭的变化。

设计人员需要预测出最在可能发生的变化,然后对它的遵循OCP原则;这需要设计人员有一定的经验,但通常都会预测错误。

对此,我们需要刺激变化:因为变化发生(发现)越早、越快就越有利;刺激变化的一些方法:

1、首先编写测试。

2、使用很短的迭代周期进行开发。

3、经常把开发特性展示给涉众。

4、首先开发最重要的特性。

5、尽早地、经常性地发布软件。尽可能频繁地把软件展示给客户和使用人员,得到他们的反馈。

4-2、良好的抽象是开放-封闭原则的基础
      遵循开放-封闭原则的代价是昂贵的,如:

创建适当的抽象是要花费开发时间和精力的;

同时,那些抽象也增加了软件设计的复杂性;

有能力处理抽象的开发人员少。

所以,对于应用程序中的每个部分都肆意地进行抽象同样不是一个好主意,正确的做法是,开发人员仅仅对程序中出现频繁变化的那些部分作出抽象,而拒绝不成熟的抽象。

后面有时间再来整理介绍面向对象分析与设计中抽象的话题。

4-3、开放-封闭原则与设计模式
      另外,Strategy(策略)模式和Template Method(模板方法)模式是满足OCP的最常用方法。

Strategy(策略)模式结构如下,可以看到通过Strategy接口很容易扩展具体的实现:

5、总结
     开放-封闭原则:

软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改的。

即:

软件质量的下降,来源于修改;

替换整个实现类,而不是修改其中的某行;

替换的扩展类可以从抽象类继承、或实现抽象接口。

提倡使用实现抽象接口的方式(面向接口编程)。

开放-封闭原则是面向对象设计的核心所在,但主要的还是基本的抽象、继承、接口的知识,这和我们平时开发息息相关,所以基础很重要。
---------------------
作者:尐譽
来源:CSDN
原文:https://blog.csdn.net/tjiyu/article/details/57079927
版权声明:本文为博主原创文章,转载请附上博文链接!

(转) 面向对象设计原则(二):开放-封闭原则(OCP)的更多相关文章

  1. [Python设计模式] 第3~5章 单一职责原则/开放-封闭原则/依赖倒转原则

    github地址:https://github.com/cheesezh/python_design_patterns 单一职责原则 就一个类而言,应该仅有一个引起它变化的原因. 如果一个类承担的职责 ...

  2. 《大话设计模式》num03-04-05---单一职责原则、开放封闭原则、依赖倒转原则

    2018年03月03日 21:19:19 独行侠的守望 阅读数个人分类: 设计模式 版权声明:本文为博主原创文章,转载请注明文章链接. https://blog.csdn.net/xiaoanzi12 ...

  3. 设计模式学习--面向对象的5条设计原则之开放封闭原则--OCP

    一.OCP简介(OCP--Open-Closed Principle):Software entities(classes,modules,functions,etc.) should be open ...

  4. 浅谈Java的开放封闭原则

    写在前面 最近, 接手了一个新业务,系统的架构可圈可点.但有些地方让人望而生畏,有些代码臃肿难以维护,让人不敢恭维.于是,结合了Java的开放封闭原则,对其中一部分代码进行了重构优化. 先来看下以前系 ...

  5. 【Python入门学习】闭包&装饰器&开放封闭原则

    1. 介绍闭包 闭包:如果在一个内部函数里,对在外部作用域的变量(不是全局作用域)进行引用,那边内部函数被称为闭包(closure) 例如:如果在一个内部函数里:func2()就是内部函数, 对在外部 ...

  6. 面向对象设计原则 开放封闭原则(Open Closed Principle)

    开放封闭原则(OCP,Open Closed Principle) 开放封闭原则是所有面向对象原则的核心. 软件设计本身所追求的目标就是封装变化.降低耦合,而开放封闭原则正是对这一目标的最直接体现. ...

  7. 北风设计模式课程---开放封闭原则(Open Closed Principle)

    北风设计模式课程---开放封闭原则(Open Closed Principle) 一.总结 一句话总结: 抽象是开放封闭原则的关键. 1."所有的成员变量都应该设置为私有(Private)& ...

  8. 开放封闭原则(Open Closed Principle)

    在面向对象的设计中有很多流行的思想,比如说 "所有的成员变量都应该设置为私有(Private)","要避免使用全局变量(Global Variables)",& ...

  9. 开放-封闭原则(OCP)开-闭原则 和 依赖倒转原则,单一职责原则

    单一职责原则 1.单一职责原则(SRP),就一个类而言,应该仅有一个引起它变化的原因 2.如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会消弱或抑制这个类完成其他职责的能力. ...

随机推荐

  1. new命令简化的内部流程

    构造函数返回对象的一些问题: function fn(name,age){ this.name = name; this.age = age; //return 23; 忽略数字,直接返回原有对象 / ...

  2. css 兼容ie8 rgba()用法

    今天遇到了一个问题,要在一个页面中设置一个半透明的白色div.这个貌似不是难题,只需要给这个div设置如下的属性即可: background: rgba(255,255,255,.1); 但是要兼容到 ...

  3. ckeditor粘帖上传图片控件-更新-2.0.15版本

    泽优Word图片上传产品测试 泽优Word图片上传控件WordPaster2,基于php开发环境测试. 泽优软件官网Word图片上传产品介绍页面: http://www.ncmem.com/webap ...

  4. multiprocessing、threading、gevent区别

    1. 进程是资源分配的单位 2. 线程是操作系统调度的单位 3. 进程切换需要的资源很最大,效率很低 4. 线程切换需要的资源一般,效率一般(当然了在不考虑GIL的情况下) 5. 协程切换任务资源很小 ...

  5. Ng第四课:多变量线性回归(Linear Regression with Multiple Variables)

    4.1  多维特征 4.2  多变量梯度下降 4.3  梯度下降法实践 1-特征缩放 4.4  梯度下降法实践 2-学习率 4.5  特征和多项式回归 4.6  正规方程 4.7  正规方程及不可逆性 ...

  6. Alpha阶段敏捷冲刺(二)

    1.提供当天站立式会议照片一张. 2.每个人的工作 (有work item 的ID),并将其记录在码云项目管理中: 昨天已完成的工作. 祁泽文:上网了解了艾宾浩斯遗忘曲线算法. 徐璐琳:找交互模块的源 ...

  7. Yeoman安装和使用详解

    Yeoman generator-react-webpack 一 什么是Yeoman Yeoman帮助我们创建项目,提供更好的工具来使我们的项目更多样化. Yeoman提供generator系统,一个 ...

  8. 14:super关键字

    本小节知识点: 1.super基本概念 2.super的作用 1.super基本概念 super是个编译器的指令符号,只是告诉编译器在执行的时候,去调谁的方法. self是一个隐私参数; self r ...

  9. codeforces 879c

    C. Short Program time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  10. Java学习--基本数据类型的定义和运算2

    例1 public class OperateDemo01{ public static void main(String args[]){ int num = 22 ; System.out.pri ...