设计模式6大原则-开闭原则

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

开闭原则理念就是当需求改变时,希望在不改变原有代码的前提下,通过扩展模块、函数来满足新需求。

开闭原则是其他五大原则的实现,也是面向对象程序设计的终极目标,它使软件实体具有一定的适应性、灵活性的同时具备稳定性和扩展性。

为什么要采用开闭原则?
(1) 开闭原则对测试的影响
已经投入使用的代码都是有意义的,需要经过 高压力、异常、错误 等严苛条件测试,换句话说,已有代码很多都是通过验证的代码,因此当提出新需求或者需求变化时,如果要修改原有代码,则所有关联模块都要重新进行单元测试、功能测试、集成测试以及验收测试,对测试是一种浪费也增加毫无意义的测试成本,如果是通过扩展添加模块或者函数来满足需求,只需要对新添加代码进行测试即可

(2) 提高代码复用性
在程序设计时尽量缩小模块、类、函数的粒度,粒度越小,被复用的可能性就越大,复用的好处?减少代码量、易于维护,避免相同的逻辑代码分散在多处(容易出错,即便是复制代码也很难保证每一处都完全相同),避免后期需求修改、bug修改时要在多处改动代码(更难以保证所有地方都能做到完全一致的修改)

(3) 提高软件的可维护性
遵守开闭原则的软件,稳定性高、扩展性好,易于维护。需求变换、增加需求时如果是通过扩展来满足需求,则维护人员无需完全读懂、理解之前功能模块的代码(有的代码有多优秀,有的代码就有多糟糕),所以相对于修改原有代码,维护人员更加希望是扩展。

如何使用开闭原则
(1) 抽象约束
抽象是对一组事务的通用描述,也就表示他可以有很多的可能性,可以跟随需求的变化而变化,因此通过接口或抽象类可以约束一组可能变化的行为,并且可以实现对扩展开放。

  • 通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的 public
  • 参数类型、引用对象尽量使用接口或抽象类,而不是实现类
  • 抽象层尽量保持稳定,一旦确定就不要修改

(2) 元数据控制模块行为
元数据:用来描述环境和数据的数据,通俗的说就是配置参数
通过扩展一个子类,修改配置文件,完成业务的变化。

(3) 制定项目章程
规定项目中所有人员必须遵守的约定。

(4) 封装变化

  • 将相同的变化封装到一个接口或抽象类中
  • 将不同的变化封装到不同的接口或抽象类中

实例
以养宠物为例,养宠物需要喂养、需要陪宠物玩,喂养不同宠物的方式是不同的,养的是宠物狗,需要带它出去溜,需要喂食狗粮,养的是宠物猫则需要用戏猫玩具逗它,需要喂食猫粮,下面看不遵循开闭原则的实现

假如刚开始只考虑养宠物狗,定义一个宠物类

    // 宠物类public class Pet{public Pet(string type){    }// 陪宠物玩public void PlayWithPet(){Console.WriteLine("陪宠物狗玩,需要带它出去溜溜");}// 喂食public void Feed(){Console.WriteLine("宠物狗需要用狗粮喂养");}}

现在还想再养一只宠物猫,修改宠物类代码

    // 宠物类public class Pet{// 宠物类型private string _type;// 构造函数传入宠物类型public Pet(string type){_type = type;}// 陪宠物玩public void PlayWithPet(){if (_type.CompareTo("Dog") == 0){Console.WriteLine("陪宠物狗玩,需要带它出去溜溜");}else if (_type.CompareTo("Cat") == 0){Console.WriteLine("陪宠物猫玩,需要拿戏猫玩具逗猫玩");}}// 喂食public void Feed(){if (_type.CompareTo("Dog") == 0){Console.WriteLine("宠物狗需要用狗粮喂养");}else if (_type.CompareTo("Cat") == 0){Console.WriteLine("宠物猫需要用猫粮喂养");}}}

虽然实现了新需求,但是原有的两个方法 PlayWithPet() 和 Feed() 都进行了修改,并且多了一些不友好的 if else if 代码,可能导致方法修改错误,并且如果再添加其他宠物类型,依然要修改原有正常运行的代码。

由于宠物猫需要买猫砂盆供其上厕所使用,宠物狗不需要,在 宠物类中再添加一个猫砂盆的方法如下

        // 猫砂盆public void CatLitterBox(){if (_type.CompareTo("Cat") == 0){Console.WriteLine("猫砂盆供猫上厕所用");}}

这样的代码设计上是不好的,那么下面看遵循开闭原则的宠物类如何设计
考虑到不同宠物用到的方法大致相同,但是具体实现各不相同,所以就将宠物类抽象出来,定义一个宠物接口 IPet ,宠物猫、宠物狗具体类分别继承该接口,根据自身特殊性,添加不同的方法,类图如下

代码实现如下

    // 宠物类接口public interface IPet{// 陪宠物玩void PlayWithPet();// 喂食void Feed();}

宠物狗具体类

    // 宠物狗public class Dog : IPet{// 陪宠物玩public void PlayWithPet(){Console.WriteLine("陪宠物狗玩,需要带它出去溜溜");}// 喂食public void Feed(){Console.WriteLine("宠物狗需要用狗粮喂养");}}

宠物猫具体类

    // 宠物猫public class Cat : IPet{// 陪宠物玩public void PlayWithPet(){Console.WriteLine("陪宠物猫玩,需要拿戏猫玩具逗猫玩");}// 喂食public void Feed(){Console.WriteLine("宠物猫需要用猫粮喂养");}// 猫砂盆public void CatLitterBox(){Console.WriteLine("猫砂盆供猫上厕所用");}}

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

  1. 设计模式之王者原则 开闭原则

    设计模式之王者原则  开闭原则 为什么说 它--开闭原则是王者原则呢? 因为所有原则都是围绕它来实现的,怎么说呢,为什么会有这么多原则呢,都是为了完成它,只要实现它你的代码就不会有什么大的问题 一.定 ...

  2. 带你认识六种设计原则(开闭原则、里氏代换原则、依赖倒转原则....)

    前言 1. 设计原则 1.1. 开-闭原则 1.2. 里氏代换原则 1.3. 依赖倒转原则 1.4. 接口隔离原则 1.5. 合成/聚合原则 1.6. 迪米特法则 前言 学习设计模式之前先要了解其中的 ...

  3. 六大设计原则--开闭原则

    定义 software entities like classes, modules and functions should be open for extension but closed for ...

  4. java开闭原则 例子_Java设计原则—开闭原则(转)

    开闭原则(Open Closed Principle)是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的.灵活的系统. 定义: 一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. S ...

  5. 设计模式--6大原则--开闭原则

    开闭原则(Open Closed Principle) 开闭原则的核心是:对扩展开放,对改动关闭 白话意思就是我们改变一个软件时(比方扩展其它功能).应该通过扩展的方式来达到软件的改变,而不应爱改动原 ...

  6. java设计模式之设计原则①开闭原则

    定义:一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 强调的是用抽象构建框架,用实现扩展细节. 优点:提高软件系统的可复用性及可维护性 例如: 创建一个Course接口 获取id方法 获取n ...

  7. 学习设计模式 - 六大基本原则之开闭原则

    设计模式总共有六大基本原则,统称为SOLID (稳定)原则,分别是S-单一职责原则(Single Responsibility Principle), O-开闭原则(Open closed Princ ...

  8. Java设计模式七大原则-开闭原则

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

  9. 设计模式之禅之开闭原则

    声明:本文为阅读秦小波所写的<设计模式之禅>所写小结,文章内容可能有部分引述此书. 开闭原则(Open Closed Principle):对扩展开放,对修改关闭 1.定义:    软件实 ...

最新文章

  1. java 常用方法_Java常用方法总结(持续更新中)
  2. 前端知识之HTML内容
  3. 用户输入一个数字,找到所有能够除尽它的数的总个数
  4. 【Git】认识各种开源协议及其关系
  5. python实现图形旋转_python轻松实现图片旋转
  6. java继承的性质_java 继承的特性
  7. compose应用_带有PostgreSQLDocker Compose for Spring Boot应用程序
  8. Apache PDFBox命令行工具:无需Java编码
  9. 华为ensp命令大全_电脑网络:华为交换机基础知识及基本命令配置大全,新手的福音...
  10. 【报告分享】2019年12月郭广昌混沌课程ppt(附下载链接)
  11. mysql多语言运营设计_多语言系统的数据库设计
  12. 【miscellaneous】语音识别工具箱综述和产品介绍
  13. 关于Centos Linux系统安装Python的问题
  14. 软件开发模式有哪些?
  15. 【有利可图网】PS实战系列:PS制作人像印章效果
  16. 我的前端“先行”之路
  17. 专家思维模型之马太效应
  18. ubuntu16.10+cuda8.0+cudnn+caffe+opencv3.2+anaconda2
  19. (新零售)商户网格化运营 - 阿里云RDS PostgreSQL最佳实践
  20. 微信企业号加密异常处理:InvalidKeyException

热门文章

  1. 易班网页版简易刷题:湖南商学院教学评估考试
  2. Leetcode 1373:二叉搜索子树的最大键值和(超详细的解法!!!)
  3. java算法集训结果填空题练习1
  4. c++ thread 带参数编译错误:/usr/include/c++/4.8/functional:1697:61: error: no type named ‘type’ in ‘class st
  5. PHP初级教程------------------(3)
  6. Windows下使用MingW编译Jsoncpp链接库
  7. 重磅发布 | 中汽协携手零数科技发布汽车数据可信存证区块链平台
  8. 套卷答题表设计(题库)
  9. 我和我老婆的年度阅读清单
  10. 简单粗暴 隐藏h5页面在微信端底部出现的白色导航条