多层嵌套if写法

我们正常多层嵌套if的写法
```java
/**
 * @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");
        }

    }
}

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

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

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

首先,建立过滤器的抽象类
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. 类数量激增,一个拦截器就一个类

最后小结一下

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