公告:九九网站目录为广大站长提供免费收录网站服务,会员可在线完成投稿无需添加友情链接。只收录内容正规合法的网站;快审网站软文10元

点击这里在线咨询客服
新站提交
  • 网站:8462
  • 待审:16
  • 小程序:9
  • 文章:3610
  • 会员:21113

 

前言

看了前一篇重构之后的代码,你可能还会有疑问:

在添加新的告警逻辑时,改动二(添加新的 handler 类)是基于扩展而非修改的方式来完成的,但改动一、三、四貌似不是基于扩展而是基于修改的方式来完成的,那改动一、三、四不就违背了开闭原则吗?

publicclassAlert{// 代码未改动... }publicclassApiStatInfo{// 省略 constructor/getter/setter 方法privateString api;privatelongrequestCount;privatelongerrorCount;privatelongdurationOfSeconds;privatelongtimeoutCount;// 改动一:添加新字段}publicabstractclassAlertHandler{// 代码未改动... }publicclassTpsAlertHandlerextendsAlertHandler{// 代码未改动...}publicclassErrorAlertHandlerextendsAlertHandler{// 代码未改动...}// 改动二:添加新的 handlerpublicclassTimeoutAlertHandlerextendsAlertHandler{// 省略代码...}publicclassApplicationContext{privateAlertRule alertRule;privateNotification notification;privateAlert alert;publicvoidinitializeBeans(){

    alertRule =newAlertRule(/*. 省略参数.*/);// 省略一些初始化代码notification =newNotification(/*. 省略参数.*/);// 省略一些初始化代码alert =newAlert();

    alert.addAlertHandler(newTpsAlertHandler(alertRule, notification));

    alert.addAlertHandler(newErrorAlertHandler(alertRule, notification));// 改动三:注册 handleralert.addAlertHandler(newTimeoutAlertHandler(alertRule, notification));

  }//... 省略其他未改动代码...}publicclassDemo{publicstaticvoidmain(String[] args){

    ApiStatInfo apiStatInfo =newApiStatInfo();//... 省略 apiStatInfo 的 set 字段代码apiStatInfo.setTimeoutCount(289);// 改动四:设置 tiemoutCount 值ApplicationContext.getInstance().getAlert().check(apiStatInfo);

}

我们先来分析一下改动一:往ApiStatInfo类中添加新的属性timeoutCount

  1. 我们不仅往ApiStatInfo类中添加了属性,还添加了对应的getter/setter方法。那这个问题就转化为:给类中添加新的属性和方法,算作 修改 还是 扩展?

我们再一块回忆一下开闭原则的定义:软件实体(模块、类、方法等)应该 对扩展开放、对修改关闭。从定义中,我们可以看出,开闭原则可以应用在不同粒度的代码中,可以是模块,也可以是类,还可以是方法(及其属性)。同样一个代码改动,在粗代码粒度下,被认定为 修改,在细代码粒度下,又可以被认定为 扩展。

  1. 比如,改动一,添加属性和方法相当于修改类,在类这个层面,这个代码改动可以被认定为 修改;但这个代码改动并没有修改已有的属性和方法,在方法(及其属性)这一层面,它又可以被认定为 扩展。

我们回到这条原则的设计初衷:只要它没有破坏原有的代码的正常运行,没有破坏原有的单元测试,我们就可以说,这是一个合格的代码改动

接下来再来分析一下改动三改动四:在ApplicationContext类的initializeBeans ()方法中,往alert对象中注册新的timeoutAlertHandler;在使用Alert类的时候,需要给check ()函数的入参apiStatInfo对象设置timeoutCount的值。

  1. 这两处改动都是在方法内部进行的,不管从哪个层面(模块、类、方法)来讲,都不能算是 扩展,而是地地道道的 修改。
  2. 在重构之后的 Alert 代码中,我们的核心逻辑集中在 Alert 类及其各个 handler 中,当我们在添加新的告警逻辑的时候,Alert 类完全不需要修改,而只需要扩展一个新 handler 类。如果我们把 Alert 类及各个 handler 类合起来看作一个 模块,那模块本身在添加新的功能的时候,完全满足开闭原则。

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

更多java原创阅读:https://javawu.com

分享到:

  admin

注册时间:

网站:0 个   小程序:3 个  文章:0 篇

  • 462

    网站

  • 9

    小程序

  • 3610

    文章

  • 113

    会员

赶快注册账号,推广您的网站吧!
热门网站
最新入驻小程序

跳一跳2022-08-22

跳一跳是微信开发的一款小游戏,有

数独大挑战2018-06-03

数独一种数学游戏,玩家需要根据9

答题星2018-06-03

您可以通过答题星轻松地创建试卷

全阶人生考试2018-06-03

各种考试题,题库,初中,高中,大学四六

运动步数有氧达人2018-06-03

记录运动步数,积累氧气值。还可偷

每日养生app2018-06-03

每日养生,天天健康