if-else嵌套太深?教你一个新手都能掌握的设计模式搞定!

栏目: IT技术 · 发布时间: 4年前

内容简介:扫码关注回复「面试」获取推文汇总

作者 l 南山狮

来源 l Hollis(ID:hollischuang)

我也不用设计模式

很多人觉得自己写的是业务代码,按照逻辑写下去,再把公用的方法抽出来复用就可以了,设计模式根本就没必要用,更没必要学。

一开始的时候,我也是这么想,直到我遇到。。。

举个栗子

我们先看一个普通的下单拦截接口。

基本逻辑,参数安全拦截,次数拦截,规则拦截,都通过,返回允许下单,任意一个失败,返回对应的失败原因。

多层嵌套if写法

我们正常多层嵌套if的写法

/**  * @author saier  * @date 2020/3/31 18:03  */ public class Order {     public Message interrupt1(){         return null;     }     public Message interrupt2(){         return null;     }     public Message interrupt3(){         return null;     }     public Message interrupt4(){         return null;     }     public Message interrupt5(){         return null;     }     public static void main(String[] args) {         Order order= new Order();         if(order.interrupt1().getResult() == 1){             if(order.interrupt2().getResult() == 1){                 if(order.interrupt3().getResult() == 1){                     if(order.interrupt4().getResult() == 1){                         if(order.interrupt5().getResult() == 1){                             System.out.println("success");                         }                     }                 }             }         }     } } @Data class Message {     private int result;     private String msg; } 

异常处理逻辑

或者有些利用异常做逻辑,代码会简单一点

/**  * @author saier  * @date 2020/3/31 18:03  */ public class Order2 {     public void interrupt1(){     }     public void interrupt2(){     }     public void interrupt3(){         //失败         throw new RuntimeException();     }     public void interrupt4(){         //失败         throw new RuntimeException();     }     public void interrupt5(){         //失败         throw new RuntimeException();     }     public static void main(String[] args) {         Order2 order2= new Order2();         try{             order2.interrupt1();             order2.interrupt2();             order2.interrupt3();             order2.interrupt4();             order2.interrupt5();             System.out.println("success");         }catch (RuntimeException e){             System.out.println("fail");         }     } } 

一开始,我就直接使用异常来做逻辑。但后续逻辑越来越复杂之后,也会出现一些问题。例如异常只能返回异常信息,不能返回更多的字段信息。

后面也留意到,异常做逻辑,在阿里规范是禁止的。

阿里代码规范 :
【强制】异常不要用来做流程控制,条件控制。
说明:异常设计的初衷是解决程序运行中的各种意外情况,且异常的处理效率比条件判断方式要低很多。

更重要的是,代码可读性太差了,随时一个方法的异常抛出来,还要考虑代码本身的异常。

没更好的办法,只能考虑 设计模式

怎么改,会使代码的可读性高,扩展性好?

在同事的提醒下,突然想起了设计模式!

我们希望达到的目的

  1. 代码没有这么多if else嵌套,可读性高

  2. 如果新增新的拦截逻辑简单方便,不影响原本的逻辑,扩展性好

  3. 可以很方便地调换拦截逻辑顺序,低耦合

责任链模式

在这种场景下,非常适合责任链模式。(什么场景使用什么设计模式,这就需要平时有积累,知道各种设计模式的基本使用)

责任链,顾名思义,就是用来处理相关事务责任的一条执行链,执行链上有多个节点,每个节点都有机会(条件匹配)处理请求事务,如果某个节点处理完了就可以根据实际业务需求传递给下一个节点继续处理或者返回处理完毕。

首先,建立过滤器的抽象类

public abstract class AbstractFilter {     private AbstractFilter nextFilter;     /**      * 责任链的下一个元素      */     public void setNextFilter(AbstractFilter nextFilter){         this.nextFilter = nextFilter;     }     public AbstractFilter getLastFilter(){         if(this.nextFilter != null){             return this.nextFilter.getLastFilter();         }else{             return this;         }     }     public void filter(FilterRequest filterRequest, Response response){         doFilter(filterRequest,response);         if(response.isFilterNext() && nextFilter != null){             nextFilter.filter(filterRequest,response);         }     }     /**      * 具体拦截逻辑      */     public abstract void doFilter(FilterRequest filterRequest, Response response);     /**      * 根据拦截结果做处理      */     public void exec(FilterRequest filterRequest, Response response){     } } 

过滤器的实现类

@Component @Order(5) public class CheckParamFilter1 extends AbstractFilter {     @Override     public void doFilter(FilterRequest filterRequest, Response response) {     } } @Component @Order(10) public class CheckParamFilter2 extends AbstractFilter {     @Override     public void doFilter(FilterRequest filterRequest, Response response) {     } } 

使用Order注解,确定过滤器的顺序,后续在spring注入的时候,会有奇效

//利用spring的自动注入机制 @Autowired List<AbstractFilter> abstractFilterList; private AbstractFilter firstFilter; //spring注入后自动执行 @PostConstruct public void initializeChainFilter(){     //把所有调用的逻辑注入到责任链,按照Order排序,越小优先级越高     for(int i = 0;i<abstractFilterList.size();i++){         if(i == 0){             firstFilter = abstractFilterList.get(i);         }else{             firstFilter.getLastFilter().setNextFilter(abstractFilterList.get(i));         }     } } //直接使用 public Response exec(){     firstFilter.filter(filterRequest, response);     return response; } 

使用设计模式的好处

看下使用责任链模式后,有什么好处!

  1. 新增拦截逻辑,只需要再实现一个AbstractFilter类即可

  2. 修改拦截顺序,只需要修改Order注解的大小,越小,优先级越高

  3. 代码清晰,所有处理逻辑下沉到实现类中

使用设计模式的缺点

做到了低耦合,高扩展。但也带来了一些不好的地方

  1. 逻辑更复杂,用了链式等数据结构,要注意单例的问题,不能重复使用

  2. 类数量激增,一个拦截器就一个类

最后小结一下

不是什么地方都适合使用设计模式,如果逻辑简单,你硬要使用设计模式,只会带来结构上的复杂,大家可以按照大家的业务场景来使用。

扫码关注回复「面试」获取推文汇总

if-else嵌套太深?教你一个新手都能掌握的设计模式搞定!


以上所述就是小编给大家介绍的《if-else嵌套太深?教你一个新手都能掌握的设计模式搞定!》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

HTTP/2基础教程

HTTP/2基础教程

Stephen Ludin、Javier Garza / 罗正龙、郑维智 / 人民邮电出版社 / 2018-1 / 49.00元

让网站和应用更快速、更简洁、更稳健,从而有效提升用户体验,这无疑是众多开发者梦寐以求的。然而互联网发展日新月异,HTTP/1.1协议已经难以满足现今的需求。在众多Web性能提升方案中,HTTP/2值得尝试。 本书是HTTP/2实用指南,介绍了HTTP/2的设计初衷和新特性,以及如何才能充分利用这些特性来打造高性能网站及应用。作者用定量分析方法,对比了不同网络环境下及不同浏览器上HTTP/1.......一起来看看 《HTTP/2基础教程》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器