开闭原则的英文全称是 Open Closed Principle,简写为 OCP。它的英文描述是:software entities (modules, classes, functions, etc.) should be open for extension , but closed for modification。即:软件实体(模块、类、方法等)应该“对扩展开放、对修改关闭”。添加一个新的功能应该是,在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)。

下面根据开闭原则重构以下代码(拆分check方法):


public class Alert {private AlertRule rule;private Notification notification;public Alert(AlertRule rule, Notification notification) {this.rule = rule;this.notification = notification;}public void check(String api, long requestCount, long errorCount, long durationOfSeconds) {long tps = requestCount / durationOfSeconds;if (tps > rule.getMatchedRule(api).getMaxTps()) {notification.notify(NotificationEmergencyLevel.URGENCY, "...");}if (errorCount > rule.getMatchedRule(api).getMaxErrorCount()) {notification.notify(NotificationEmergencyLevel.SEVERE, "...");}}
}

重构思路:

(1)将 check() 函数的多个入参封装成 ApiStatInfo 类;

(2)引入 handler 的概念,将 if 判断逻辑分散在各个 handler 中(使用责任链模式的变体,所有handler节点都遍历执行)。


public class Alert {private List<AlertHandler> alertHandlers = new ArrayList<>();public void addAlertHandler(AlertHandler alertHandler) {this.alertHandlers.add(alertHandler);}public void check(ApiStatInfo apiStatInfo) {for (AlertHandler handler : alertHandlers) {handler.check(apiStatInfo);}}
}@Data
public class ApiStatInfo {private String api;private long requestCount;private long errorCount;private long durationOfSeconds;
}public abstract class AlertHandler {protected AlertRule rule;protected Notification notification;public AlertHandler(AlertRule rule, Notification notification) {this.rule = rule;this.notification = notification;}public abstract void check(ApiStatInfo apiStatInfo);
}public class TpsAlertHandler extends AlertHandler {public TpsAlertHandler(AlertRule rule, Notification notification) {super(rule, notification);}@Overridepublic void check(ApiStatInfo apiStatInfo) {long tps = apiStatInfo.getRequestCount()/ apiStatInfo.getDurationOfSeconds();if (tps > rule.getMatchedRule(apiStatInfo.getApi()).getMaxTps()) {notification.notify(NotificationEmergencyLevel.URGENCY, "...");}}
}public class ErrorAlertHandler extends AlertHandler {public ErrorAlertHandler(AlertRule rule, Notification notification){super(rule, notification);}@Overridepublic void check(ApiStatInfo apiStatInfo) {if (apiStatInfo.getErrorCount() > rule.getMatchedRule(apiStatInfo.getApi()).getMaxErrorCount()) {notification.notify(NotificationEmergencyLevel.SEVERE, "...");}}
}

重构之后的代码更加灵活和易扩展。如果我们要想添加新的告警逻辑,只需要基于扩展的方式创建新的 handler 类即可,不需要改动原来的 check() 函数的逻辑。而且,我们只需要为新的 handler 类添加单元测试,老的单元测试都不会失败,也不用修改。

在重构之后的 Alert 代码中,我们的核心逻辑集中在 Alert 类及其各个 handler 中,当我们在添加新的告警逻辑的时候,Alert 类完全不需要修改,而只需要扩展一个新 handler 类。如果我们把 Alert 类及各个 handler 类合起来看作一个“模块”,那模块本身在添加新的功能的时候,完全满足开闭原则。

并且,我们要认识到,添加一个新功能,不可能任何模块、类、方法的代码都不“修改”,这个是做不到的。类需要创建、组装、并且做一些初始化操作,才能构建成可运行的的程序,这部分代码的修改是在所难免的。我们要做的是尽量让修改操作更集中、更少、更上层,尽量让最核心、最复杂的那部分逻辑代码满足开闭原则。

实际上,多态、依赖注入、基于接口编程,以及前面提到的抽象意识,说的都是同一种开闭原则设计思路,只是从不同的角度、不同的层面来阐述而已。这也体现了“很多设计原则、思想、模式都是相通的”这一思想。

“唯一不变的只有变化本身”。没必要为一些遥远的、不一定发生的需求去做过度设计。最合理的做法是,对于一些比较确定的、短期内可能就会扩展,或者需求改动对代码结构影响比较大的情况,或者实现成本不高的扩展点,在编写代码的时候之后,我们就可以事先做些扩展性设计。

【设计原则】开闭原则(对扩展开放、对修改关闭)相关推荐

  1. 如何做到“对扩展开放、修改关闭”?

    我们来学习 SOLID 中的第二个原则:开闭原则.我个人觉得,开闭原则是 SOLID 中最难理解.最难掌握,同时也是最有用的一条原则. 之所以说这条原则难理解,那是因为,"怎样的代码改动才被 ...

  2. 面向对象软件设计的“开—闭”原则

    1.什么是开闭原则         "开-闭"原则是指软件实体应当对扩展性开放,对修改关闭.即软件实体应该在不修改的前提下扩展,这个原则实际上为软件设计指明了目标.我们知道软件设计 ...

  3. 【设计模式】软件设计七大原则 ( 开闭原则 )

    文章目录 一.开闭原则简介 二.开闭原则代码示例 1.商品接口 2.普通商品类 3.折扣商品类 4.测试类 一.开闭原则简介 开闭原则 : 定义 : 一个 软件实体 , 类 / 模块 / 函数 , 对 ...

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

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

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

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

  6. 一周技术学习笔记(第67期)-CPU的设计跟开闭原则有关系吗

    你能想到CPU的设计是开闭原则的设计吗 说CPU的设计很符合软件设计的开闭原则,估计一般的同学肯定不会这样意识到.其实我也一样不太可能把它们能够想在一起,并将它们关联起来. 可确实就这样发生了.实际上 ...

  7. 六大设计模式原则-开闭原则

    一.开闭原则定义 开闭原则是面向对象的可复用设计的第一块基石,是最重要的面向对象设计原则.定义如下: 开闭原则(Open-Closed Principle, OCP):一个软件实体应当对扩展开放,对修 ...

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

    设计模式6大原则-开闭原则 定义:一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 开闭原则理念就是当需求改变时,希望在不改变原有代码的前提下,通过扩展模块.函数来满足新需求. 开闭原则是其他 ...

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

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

  10. 设计一个扩展自抽象类geometricobject的新的triangle类_面向对象设计原则之开放封闭原则(开闭原则OCP)...

    (1) 定义 一个软件实体(类.模块.函数等),对于扩展是开放的,对于更改是封闭的. 对于扩展是开放的:这意味着模块的行为是可以扩展的.当应用的需求发生改变时,我们可以对模块进行扩展,比如增加新的类或 ...

最新文章

  1. 资源 | 2018年值得关注的200场机器学习会议(建议收藏)
  2. vue 圆形百分比进度条_快速构建一个圆形的进度条
  3. 《追风行动》有点儿意思
  4. vue项目和react项目中禁止eslint
  5. 来一个可能防止恶意采集和爬虫的SH
  6. vscode php函数提醒,解决vscode格式保存后出现的问题
  7. 中毒后重装系统该注意的几点
  8. 使用Python把树莓派改造成一个语音助手
  9. Sql Server 2005 64位安装包
  10. linux系统date命令(时间戳与日期相互转换)
  11. 研究生新人如何高效读论文-方法积累笔记
  12. Android Red5视频通讯第一篇:连接服务器
  13. 解决AssertionError Torch not compiled with CUDA enabled问题
  14. 华科计院数据库课程笔记
  15. 保存rdl文件到报表服务器,在SQL服务器上将RDL报表导出成Excel XLS XLSX SpreadsheetML格式...
  16. 照片的35x45,300dpi怎么弄
  17. 安装angular脚手架
  18. NOIP 2015 简记
  19. mp4文件播放不了怎么办?
  20. ctf php 流量分析题,CTF平台hackit题目分析与解答

热门文章

  1. 第一次面试,收到offer后被拒绝
  2. 如何使用 SHC 加密 Shell 脚本
  3. 再见了 HDFS!这个资源调度框架已成气候!
  4. 用什么软件抓cd音轨音质最好_开车不嗨皮,那跟咸鱼有什么区别
  5. 《数字图像处理 冈萨雷斯》绪论——学习笔记
  6. VBA开发:设置单元格数据有效性
  7. 手机浏览器微信h5支付
  8. Mac OS开发者软件清单
  9. 计算机毕业设计SSM宠物领养系统【附源码数据库】
  10. java工具多,[转帖]一个 Java 工具到底有多大?