如何在JAVA编程中干掉if/else、switch/case(三) 绝地灬酷狼 2022-01-26 23:05 384阅读 0赞 前言 前面的文章咱们通过表驱动法、策略模式两种方法替换掉JAVA代码里的if...else和switch...case,今天继续介绍第三种方法:责任链设计模式。在WEB应用中,大名鼎鼎的filter链就是责任链模式的具体实现。在笔者一个实际项目中就用到责任链模式,来看看吧。 **场景** 所有移动端app开发,都会面临一个问题:升级!后台在开发升级接口时,会判断很多逻辑,比如版本是否在升级的范围内、操作系统是否符合、内存、芯片类型、地区、根据ip灰度升级等,以上任何一个不符合就不升级。 还有一种场景,视频播放鉴权。比如爱奇艺、优酷、腾讯等公司的视频播放需要鉴权的,比如判断视频是否收费、判断该地域是否能播放、如果视频支持4K当前设备是否支持等。 以上两种场景很多人,拿到需求第一步肯定想到if...else判断。比如下面代码: //升级判断public boolean upgrade() { try { if (!版本在范围内) { return false; } if(!操作系统符合){ return false; } ... } catch (Exception e) { log.error("异常发生,messge=" + msg, e); } } //播放鉴权public boolean update() { try { if (视频收费,用户不是vip) { return false; } if(视频是4K,设备不支持){ return false; } ... } catch (Exception e) { log.error("异常发生,messge=" + msg, e); } } 以上代码,会存在大量的if...else代码,最重要的是如果新增判断怎么办?需要修改这个类,增加新的if判断,这就不符合JAVA的对修改关闭原则,以上问题都是典型的责任链模式解决方案,责任链模式对扩展开放原则,新增加判断只需要增加类即可,不修改原代码。 **责任链模式** 定义:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。职责链模式结构如图所示: ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2plazEyMzQ1Ng_size_16_color_FFFFFF_t_70][] 在职责链模式结构图中包含如下几个角色: ● Handler(抽象处理者):它定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法。因为每一个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个抽象处理者类型的对象(如结构图中的successor),作为其对下家的引用。通过该引用,处理者可以连成一条链。 ● ConcreteHandler(具体处理者):它是抽象处理者的子类,可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发。 具体处理者是抽象处理者的子类,它具有两大作用:第一是处理请求,不同的具体处理者以不同的形式实现抽象请求处理方法handleRequest();第二是转发请求,如果该请求超出了当前处理者类的权限,可以将该请求转发给下家。这样形成了一个链式结构,如下图所示: ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2plazEyMzQ1Ng_size_16_color_FFFFFF_t_70 1][] **升级接口实现** 回到上面的问题,我们如何设计升级这个接口呢?首先,从上面的结构图看,需要首先创建一个接口AbstractUpgradeCheckHandler: public abstract class AbstractUpgradeCheckHandler<T1, T2> { protected AbstractUpgradeCheckHandler handler; /** * 设置后续处理器 * * @param handler */ public void setNextHandler(AbstractUpgradeCheckHandler handler) { this.handler = handler; } /** * 升级检查逻辑处理 * * @param request 请求参数信息 * @param upInfo 存在的版本升级信息 * @return */ public abstract boolean check(T1 request, T2 upInfo); } 具体的子handler都实现这个接口AbstractUpgradeCheckHandler,例如 VerNoCheckHandler、OpCheckHandler代码如下: @Order(1)@Componentpublic class VerNoCheckHandler extends AbstractUpgradeCheckHandler<Request, UpdateInfo> { @Override public boolean check(Request request, UpgradeInfo upgradeInfo) { //版本处理逻辑 }} @Order(2)@Componentpublic class OpCheckHandler extends AbstractUpgradeCheckHandler<Request, UpdateInfo> { @Override public boolean check(Request request, UpgradeInfo upgradeInfo) { //操作系统安保处理逻辑 }} Handler链工厂类:UpgradeCheckHandlerFactory: @Componentpublic class UpgradeCheckHandlerFactory { @Autowired private List<AbstractUpgradeCheckHandler<Request, UpgradeInfo>> upgradeCheckHandlers; private AbstractUpgradeCheckHandler headHandler; public AbstractUpgradeCheckHandler createHandlerChain() { if(headHandler != null) return headHandler; AbstractUpgradeCheckHandler preHandler = null; for(AbstractUpgradeCheckHandler handler : upgradeCheckHandlers) { if(preHandler != null) preHandler.setNextHandler(handler); else headHandler = handler; preHandler = handler; } return headHandler; }} 实际调用如下, AbstractUpgradeCheckHandler<Request, UpgradeInfo> upgradeCheckHandler = upgradeCheckHandlerFactory .createHandlerChain();if (upgradeCheckHandler.check(request, upgradeInfo)) { //升级} else { //不升级} 即使,后续新增需求,比如增加按照升级时间来进行判断,只需要新建一个UpgradeTimeCheckHandler加入到处理链里就OK了,这就是前面说的对扩展开放。 至此,如何在JAVA编程中干掉if/else、switch...case三篇完结了,希望你能有所收获。 关注公众号:JAVA取经之旅 ![20190524153424327.jpg][] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2plazEyMzQ1Ng_size_16_color_FFFFFF_t_70]: /images/20220127/9a2d47f0169c4c3fb3a0850c19e2382e.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2plazEyMzQ1Ng_size_16_color_FFFFFF_t_70 1]: /images/20220127/d394c7b874134a7c9853661af47e4e3d.png [20190524153424327.jpg]: /images/20220127/3388f3ab7d4e4dcdb2b9c324cfb7d596.png
还没有评论,来说两句吧...