ZT 设计模式六大原则(6):开闭原则

分类: 设计模式 2012-02-27 08:48 24870人阅读 评论(72) 收藏 举报

定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。

问题由来:在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。

解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。

开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统。开闭原则可能是设计模式六项原则中定义最模糊的一个了,它只告诉我们对扩 展开放,对修改关闭,可是到底如何才能做到对扩展开放,对修改关闭,并没有明确的告诉我们。以前,如果有人告诉我“你进行设计的时候一定要遵守开闭原 则”,我会觉的他什么都没说,但貌似又什么都说了。因为开闭原则真的太虚了。

在仔细思考以及仔细阅读很多设计模式的文章后,终于对开闭原则有了一点认识。其实,我们遵循设计模式前面5大原则,以及使用23种设计模式的目的就是遵循 开闭原则。也就是说,只要我们对前面5项原则遵守的好了,设计出的软件自然是符合开闭原则的,这个开闭原则更像是前面五项原则遵守程度的“平均得分”,前 面5项原则遵守的好,平均分自然就高,说明软件设计开闭原则遵守的好;如果前面5项原则遵守的不好,则说明开闭原则遵守的不好。

其实笔者认为,开闭原则无非就是想表达这样一层意思:用抽象构建框架,用实现扩展细节。因为 抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节,我们用从抽象派生的实现类来进行扩展,当软件需要发生变化 时,我们只需要根据需求重新派生一个实现类来扩展就可以了。当然前提是我们的抽象要合理,要对需求的变更有前瞻性和预见性才行。

说到这里,再回想一下前面说的5项原则,恰恰是告诉我们用抽象构建框架,用实现扩展细节的注 意事项而已:单一职责原则告诉我们实现类要职责单一;里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;接口隔离原则告诉我们 在设计接口的时候要精简单一;迪米特法则告诉我们要降低耦合。而开闭原则是总纲,他告诉我们要对扩展开放,对修改关闭。

最后说明一下如何去遵守这六个原则。对这六个原则的遵守并不是是和否的问题,而是多和少的问题,也就是说,我们一般不会说有没有遵守,而是说遵守程度的多 少。任何事都是过犹不及,设计模式的六个设计原则也是一样,制定这六个原则的目的并不是要我们刻板的遵守他们,而需要根据实际情况灵活运用。对他们的遵守 程度只要在一个合理的范围内,就算是良好的设计。我们用一幅图来说明一下。

图中的每一条维度各代表一项原则,我们依据对这项原则的遵守程度在维度上画一个点,则如果对这项原则遵守的合理的话,这个点应该落在红色的同心圆内部;如 果遵守的差,点将会在小圆内部;如果过度遵守,点将会落在大圆外部。一个良好的设计体现在图中,应该是六个顶点都在同心圆中的六边形。

在上图中,设计1、设计2属于良好的设计,他们对六项原则的遵守程度都在合理的范围内;设计3、设计4设计虽然有些不足,但也基本可以接受;设计5则严重不足,对各项原则都没有很好的遵守;而设计6则遵守过渡了,设计5和设计6都是迫切需要重构的设计。

到这里,设计模式的六大原则就写完了。主要参考书籍有《设计模式》《设计模式之禅》《大话设计模式》以及网上一些零散的文章,但主要内容主要还是我本人对 这六个原则的感悟。写出来的目的一方面是对这六项原则系统地整理一下,一方面也与广大的网友分享,因为设计模式对编程人员来说,的确非常重要。正如有句话 叫做一千个读者眼中有一千个哈姆雷特,如果大家对这六项原则的理解跟我有所不同,欢迎留言,大家共同探讨。

下面是前面5项设计原则的链接

1.  单一职责原则(Single Responsibility Principle)

2.  里氏替换原则(Liskov Substitution Principle)   //父类不要隐藏子类

3.  依赖倒置原则(Dependence Inversion Principle)//模板模式

4.  接口隔离原则(Interface Segregation Principle)//接口尽量小(别臃肿),但是要有限度

5.  迪米特法则(Law Of Demeter)//最少知道原则

同时为了方便想收藏的朋友,下面给出word版本的下载。

word版本下载链接:设计模式六大原则

ZT 设计模式六大原则(6):开闭原则的更多相关文章

  1. Java设计模式(1:软件架构设计七大原则及开闭原则详解)

    前言 在日常工作中,我们使用Java语言进行业务开发的时候,或多或少的都会涉及到设计模式,而运用好设计模式对于我而言,又是一个比较大的难题.为了解决.克服这个难题,笔主特别开了这个博客来记录自己学习的 ...

  2. 设计原则:开-闭原则(Open-Closed Principle, OCP)

    开-闭原则就是软件实体应当对扩展开放,对修改关闭.(Software entities should be open for extension,but closed for modification ...

  3. 设计原则:开闭原则(OCP)

    1.什么是开闭原则 开闭原则的英文是Open Closed Principle,缩写就是OCP.其定义如下: 软件实体(模块.类.方法等)应该"对扩展开放.对修改关闭". 从定义上 ...

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

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

  5. 7.10 其他面向对象设计原则1: 开-闭原则OCP

    其他面向对象设计原则1: 开-闭原则OCP  Open-Closed Principle (OCP)5.1 设计变坏的前兆 Signs of Rotting Design  僵硬性 Rigidit ...

  6. js 的七大原则--单一原则、开闭原则、替换原则(一)

    一.前言: js 的七大设计原则: 1.单一原则 2.开闭原则 3.里氏替换原则 4.依赖倒转原则 5.接口隔离原则 6.合成复用原则 7.迪米尔法则 二.单一原则 1.定义:单一原则就是一个对象或者 ...

  7. [设计模式]<<设计模式之禅>>关于开闭原则

    开闭原则是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的.灵活的系统,先来看开闭原则的定义: Software entities like classes,modules and fun ...

  8. 设计模式课程 设计模式精讲 3-3 开闭原则 coding

    1 课程讲解 1.1 开闭原则定义 1.2 不重要内容 2 代码coding 2.1 基类 2.2 需求:打印出原价和折扣后的价格.(接口不应该随意变化,面向接口编程) 1 课程讲解 1.1 开闭原则 ...

  9. 深入理解JavaScript系列(7):S.O.L.I.D五大原则之开闭原则OCP

    前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第2篇,开闭原则OCP(The Open/Closed Principle ). 开闭原则的描述是: Software ...

  10. Java的开发—面向对象的7大原则之开闭原则(一)

    开闭原则(Open Close Principle) 一.定义: 软件中的(类.模块.函数等等)应该对于扩展是开放的,对于修改时关闭的.意味着一个实体允许在不改变它的源代码的前提变更它的行为 这里的软 ...

随机推荐

  1. LinuxShell脚本编程基础1-vi编辑器的使用

    1.输入模式与命令模式的切换 按 [Esc]键 切换到 命令模式: 2.保存与退出 :w mytest.txt 保存文件名 :q 退出 :q! 强制退出 :wq  保存并退出 3.插入文本命令 i 在 ...

  2. android httpclient 上传图片

    需要依赖  httpmime.jar /** * 上传图片 * * @param url * 上传地址 * @param filepath * 图片路径 * @return */ public Str ...

  3. C语言实现链表

    #include<stdio.h>#include<malloc.h>#include<stdlib.h> typedef struct Node {    int ...

  4. [转]微信小程序开发:http请求

    本文转自:http://www.cnblogs.com/dragondean/p/5921079.html 在微信小程序进行网络通信,只能和指定的域名进行通信,微信小程序包括四种类型的网络请求. 普通 ...

  5. POJ 1185 炮兵阵地 经典的 状态压缩dp

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16619   Accepted: 6325 Description ...

  6. When a java class is load by classloader, where the constant poll be put?

    Q:When a java class is load by classloader, where the constant poll be put? A:the "Non-Heap Mem ...

  7. spring 代理

    java动态代理实现 1. Java自带的动态代理,反射生成字节码 2. Cglib调用asm生成子类 spring 中代理实现 1. 如果类实现了接口,使用java动态代理 2. 没有实现接口,使用 ...

  8. 廖雪峰JavaScript练习题2

    请把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字.输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart'] 肯定有更简单的方法, ...

  9. sass判断语句

    @if判断 @if可一个条件单独使用,也可以和@else结合多条件使用 scss.style css.style 三目判断 语法为:if($condition, $if_true, $if_false ...

  10. git 命令收藏

    git init # 初始化本地git仓库(创建新仓库)   git config --global user.name "xxx" # 配置用户名   git config -- ...