栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

工作中常用到的设计模式-业务校验的设计

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

工作中常用到的设计模式-业务校验的设计

一、概述

工作中比较常见的业务场景,比如对外提供一个数据上传接口,基本的业务逻辑,一般都有参数非空校验、安全校验(比如IP、非正常请求等)、黑白名单校验、规则拦截等等。很多开发伙伴会使用异常来实现。

public class Upload{

    public void checkNullParam(Object param){
      //参数非空校验
      throw new RuntimeException();
    }
    public void checkSecurity(){
      //安全校验
      throw new RuntimeException();
    }
    public void checkBackList(){
        //黑名单校验
        throw new RuntimeException();
    }
    public void checkRule(){
        //规则拦截
        throw new RuntimeException();
    }
}

二、业务校验的设计

上面的示例代码使用了异常来做逻辑条件判断,如果后续逻辑越来越复杂的话,会出现一些问题:如异常只能返回异常信息,不能返回更多的字段,这时候需要自定义异常类。而且异常的处理效率比条件判断方式要低很多。

阿里开发手册规定:禁止用异常做逻辑判断 ,这里可以考虑责任链模式。

责任链模式:将处理不同逻辑的对象连接成一个链表结构,每个对象都保存下一个节点的引用:

  • 一个接口或者抽象类
  • 每个对象差异化处理
  • 对象链(数组)初始化(连起来)

2.1 一个接口或者抽象类

  • 有一个指向责任下一个对象的属性
  • 一个设置下一个对象的set方法
  • 给子类对象差异化实现的方法(如代码中的doFilter方法)
public abstract class AbstractHandler {

    //责任链中的下一个对象
    private AbstractHandler nextHandler;

    
    public void setNextHandler(AbstractHandler nextHandler){
        this.nextHandler = nextHandler;
    }
    
    public AbstractHandler getNextHandler() {
        return nextHandler;
    }


    
    public void filter(Request request, Response response) {
        doFilter(request, response);
        if (getNextHandler() != null) {
            getNextHandler().filter(request, response);
        }
    }


    
    abstract void doFilter(Request filterRequest, Response response);

}

2.2 每个对象差异化处理

@Component
@Order(1) //顺序排第1,最先校验
public class CheckParamFilterObject extends AbstractHandler {

    @Override
    public void doFilter(Request request, Response response) {
        System.out.println("非空参数检查");
    }
}
@Component
@Order(2) //校验顺序排第2
public class CheckBlackFilterObject extends AbstractHandler {

    @Override
    public void doFilter(Request request, Response response) {
        //校验黑名单
        System.out.println("校验黑名单");
    }
}
@Component
@Order(3) //校验顺序排第3
public class CheckRuleFilterObject extends AbstractHandler {

    @Override
    public void doFilter(Request request, Response response) {
        //check rule
        System.out.println("check rule");
    }
}

2.3 对象链初始化(责任链连起来)&& 使用

@Component("ChainPatternDemo")
public class ChainPatternDemo {

    //自动注入各个责任链的对象
    @Autowired
    private List abstractHandleList;

    private AbstractHandler abstractHandler;

    //spring注入后自动执行,责任链的对象连接起来
    @PostConstruct
    public void initializeChainFilter(){

        for(int i = 0;i
            if(i == 0){
                //责任链的第一个节点
                abstractHandler = abstractHandleList.get(0);
            }else{
                //责任链的对象连接起来
                AbstractHandler currentHander = abstractHandleList.get(i - 1);
                AbstractHandler nextHander = abstractHandleList.get(i);
                currentHander.setNextHandler(nextHander);
            }
        }
    }

    //使用---直接调用exec
    public Response exec(Request request, Response response) {
        abstractHandler.filter(request, response);
        return response;
    }

    public AbstractHandler getAbstractHandler() {
        return abstractHandler;
    }

    public void setAbstractHandler(AbstractHandler abstractHandler) {
        this.abstractHandler = abstractHandler;
    }
}

三、责任链总结

优点:

  • 1 将请求与处理解耦。
  • 2 请求处理者将不是自己职责范围内的请求,转发给下一个节点。
  • 3 请求发送者不需要关系链路结构,只需等待请求处理结果即可。
  • 4 链路结构灵活,易于扩展新的请求处理节点

缺点:

  • 责任链太长或者处理时间过长,会影响整体性能。
  • 如果节点对象存在循环引用,则会造成死循环,导致程序崩溃。

我目前的项目中,业务校验是把doFilter() 返回值优化成 Boolean类型,然后在filter() 方法中判断为true才继续往下调用,这样可以提升整体的性能。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/870602.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号