• 【java设计模式】(9)---责任链模式(案例解析)


    一、概念

    1、理解责任链模式

    责任链模式是一种对象的行为模式,责任链模式实际上是一种处理请求的模式 它让多个处理器(对象节点)都有机会处理该请求,请求通过这条加工链进行一步步的处理后。输出最终的产品产出。

    2、JDK中的责任链模式示例

    让我们看一下JDK中责任链模式的例子,然后我们将继续实现这种模式的真实例子。我们知道在try-catch块代码中我们可以有多个catch块。这里每个catch块都是处理该特定异常的处理器。

    因此当try块中发生任何异常时,它会发送到第一个catch块进行处理。如果catch块无法处理它,它会将请求转发到链中的下一个对象,即下一个catch块。如果即使最后一个catch块也无法处理它,那么异常将被抛出链接到调用程序。

    3、责任链模式使用

    责任链模式怎么使用呢?

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

    二、举例演示

    我们在项目处理请求的时候,一个请求过来,我们可以进行 1)非空参数检查 2)安全调用校验 3)校验黑名单 4)规则拦截对象 这些就是一个责任链。

    按照上面的使用说明规则,来建好相应的类,进行演示。

    1、一个接口或者抽象类

    这个接口或者抽象类,需要:

    • 有一个指向责任下一个对象的属性
    • 一个设置下一个对象的set方法
    • 给子类对象差异化实现的方法(如以下代码的doFilter方法)
    /**
      * @Description: 定义一个接口或者抽象类
      */
    public abstract class AbstractHandler {
    
        /**
         * 责任链中的下一个对象
         */
        private AbstractHandler nextHandler;
        
        // 具体参数拦截逻辑,给子类去实现
        public void filter(HttpServletRequest request, HttpServletResponse response) {
            //执行当前链
            doFilter(request, response);
            //如果还有下个链,执行下个链
            if (getNextHandler() != null) {
                getNextHandler().filter(request, response);
            }
        }
    
        //获取下一个链对象
        public AbstractHandler getNextHandler() {
            return nextHandler;
        }
        
        //插入责任链的下一个对象
        public void setNextHandler(AbstractHandler nextHandler){
            this.nextHandler = nextHandler;
        }
    
        abstract void doFilter(HttpServletRequest request, HttpServletResponse response);
    }
    

    2、每个对象差异化处理

    责任链上,每个对象的差异化处理,如本小节的业务场景,就有参数校验对象、安全校验对象、黑名单校验对象、规则拦截对象。

    /**
     * 1、参数校验对象
     **/
    @Component
    @Order(1) //顺序排第1,最先校验
    public class CheckParamFilterObject extends AbstractHandler {
    
        @Override
        public void doFilter(HttpServletRequest request, HttpServletResponse response) {
            System.out.println("1、非空参数检查");
        }
    }
    
    /**
     *  2、安全校验对象
     */
    @Component
    @Order(2) //校验顺序排第2
    public class CheckSecurityFilterObject extends AbstractHandler {
    
        @Override
        public void doFilter(HttpServletRequest request, HttpServletResponse response) {
            //invoke Security check
            System.out.println("2、安全调用校验");
        }
    }
    
    /**
     *  3、黑名单校验对象
     */
    @Component
    @Order(3) //校验顺序排第3
    public class CheckBlackFilterObject extends AbstractHandler {
    
        @Override
        public void doFilter(HttpServletRequest request, HttpServletResponse response) {
            //invoke black list check
            System.out.println("3、校验黑名单");
        }
    }
    
    /**
     *  4、规则拦截对象
     */
    @Component
    @Order(4) //校验顺序排第4
    public class CheckRuleFilterObject extends AbstractHandler {
    
        @Override
        public void doFilter(HttpServletRequest request, HttpServletResponse response) {
            //check rule
            System.out.println("4、规则拦截对象");
        }
    }
    

    3 对象链连起来(初始化)

    /**
      * @Description: 对象链连起来(初始化)对象
      */
    @Component("ChainPatternDemo")
    public class ChainPatternDemo {
    
        //自动注入各个责任链的对象
        @Autowired
        private List<AbstractHandler> abstractHandleList;
    
        private AbstractHandler abstractHandler;
    
        //spring注入后自动执行,责任链的对象连接起来
        @PostConstruct
        public void initializeChainFilter(){
    
            for(int i = 0;i<abstractHandleList.size();i++){
                if(i == 0){
                    //因为上面@Order(1)拍过序 所以第一个就是 非空参数检查
                    abstractHandler = abstractHandleList.get(0);
                }else{
                    AbstractHandler currentHander = abstractHandleList.get(i - 1);
                    AbstractHandler nextHander = abstractHandleList.get(i);
                    currentHander.setNextHandler(nextHander);
                }
            }
        }
    
        //直接调用这个方法使用,返回最后处理好的response
        public HttpServletResponse exec(HttpServletRequest request, HttpServletResponse response) {
            //这里 abstractHandler 就是第一个 接下来就会一个一个向下
            abstractHandler.filter(request, response);
            return response;
        }
    }
    

    4、使用演示

    @RestController
    public class PayController {
    
        @Autowired
        private ChainPatternDemo chainPatternDemo;
    
        @RequestMapping("/testHandler")
        public  void testHandler(HttpServletRequest req, HttpServletResponse resp){
            //调用责任链
            chainPatternDemo.exec(req,resp);
        }
    }
    

    运行结果

    1、非空参数检查
    2、安全调用校验
    3、校验黑名单
    4、规则拦截对象
    

    完美!

    总结 当我们在开发中有一个对象需要多次处理的时候,就可以考虑用责任链设计模式,上面的示例也完全可以用于实际开发中。


    参考

    1、实战!工作中常用到哪些设计模式 非常感谢!



  • 相关阅读:
    函数对象、名称空间与作用域
    函数
    leetcode语法练习(二)
    leetcode语法练习(一)
    字符编码与文件操作
    集合类型内置方法与总结
    列表,元组与字典类型
    数据类型内置方法之数据类型与字符串类型
    [SVG实战]饼图全面解析
    [JavaScript语法学习]重新认识JavaScript
  • 原文地址:https://www.cnblogs.com/qdhxhz/p/15478383.html
Copyright © 2020-2023  润新知