• java设计模式---责任链模式详解


    一,责任链模式

    1,什么是责任链模式

    责任链模式:Chain of Responsibility Patten 。就是将链中的每一个结点看做是一个对象,每个结点处理请求均不同,且内部自动维护一个下一个结点对象。当请求从链条的首端出发时,会沿着链的路径依次传递给每一个结点的对象,直到有对象处理这个请求为止。

    就是说每个结点会处理一件事情,如果结点间出现异常,那么链路就会中断。

    一般比如说一个请假需要多个负责任审批,过五关斩六将等这些,都是责任链模式。

    二,框架中使用到的责任链模式

    各个框架中用到了责任链模式如下,根据本人所读的框架源码所累积的,如有缺漏,欢迎补充

    1,springmvc流程

    就拿这个springMvc的执行流程来说,全部流程就组成了一个链条。每一个步骤就是一个结点,每个结点都会有对应的处理方法,每个结点处理完成之后,就会进入下一个结点。一旦某个结点出现异常,那么当前的链路就会停止,当前请求中断。
    在这里插入图片描述

    2,mybatis的执行流程

    mybatis的执行流程也是通过这个责任链模式,如首先会创建这个SqlSessionFactory,然后通过这个工厂创建一个SqlSession,这个SqlSession只是一个门面模式,会通过Executer执行增删改查的操作,然后一个Handler用于设置参数,一个Handler用于返回结果集,最后通过这个StatementHandler将执行结果获取。里面的整个步骤就相当于形成了一个链条,执行完当前结点就会进入下一个结点,如果出现异常,链条终止往下执行。
    在这里插入图片描述

    3,spring的过滤器和拦截器

    spring里面的这个过滤器链路的调用,以及拦截器的链路调用,也是采用这种责任链模式
    在这里插入图片描述

    4,sentinel限流熔断

    sentinel里面的每一个规则对应一个槽点,如流控规则,授权规则,熔断规则,热点规则,系统规则等。里面也是利用这个责任链模式,每个插槽对应一个规则,每个规则处理一个事件。如果出现异常,那么就会进行对应的限流降级。
    在这里插入图片描述

    5,aop的加载和使用

    aop依赖与ioc,在生产bean并进行实例化之前,先通过bean的第一个后置处理器找到所有在类上面加@AspectJ这个注解的所有类,并在这个类的里面找到所有的befeore,after等注解的方法,每一个before,after等都会生成一个对应的advisor,每个advisor包括advise和pointcut,advise主要是用来作为一个增强器的使用,pointcut是为了进行匹配,匹配成功才进行最终的动态代理的生成。最后获取到所有的advisors,由于可能有大量的advisor,因此在bean的最后一个后置处理器才对这些所有的advisor进行处理,即在bean进行初始化之后才进行处理。最后会去循环遍历这些advisors,通过advisors里面封装的pointcut和生成的advisor进行比较,如果匹配成功,则说明bean需要创建动态代理。主要是通过责任链的方式实现。

    三,自定义一个责任链模式

    结下来举一个案例说明一下这个责任链模式。

    1,需求

    假设有一个学校有一个采购审批的需要,采购项目需要给领导审批,不同金钱范围,对应的审批领导的等级不同,如下:

    1,金额小于5000,由教学主任审批

    2,金额小于等于5000,由院长审批

    3,金额小于等于30000,由副校长任审批

    4,金额大于30000,由校长审批

    2,编码

    在这里插入图片描述

    1,接下来进入这个编码环节。首先定义一个实体类ApproverRequest

    /**
     * @Author: zhenghuisheng
     * @Date: 2022/9/11 21:19
     */
    public class ApproverRequest {
    	private int type = 0; //请求类型
    	private float price = 0.0f; //请求金额
    	private int id = 0;
    	//构造器
    	public ApproverRequest(int type, float price, int id) {
    		this.type = type;
    		this.price = price;
    		this.id = id;
    	}
    	public int getType() { return type; }
    	public float getPrice() { return price; }
    	public int getId() { return id; }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2,在写一个抽象类,用于定义全局,作为子类的规范。链条中所有的结点都需要继承子类,实现子类里面的抽象方法

    /**
     * @Author: zhenghuisheng
     * @Date: 2022/9/11 21:09
     * 定义全局
     */
    public abstract class Approver {
        //下一个调用者
        Approver next ;
        //需要传入的名字
        String name ;
    
        public Approver(String name){
            this.name = name;
        }
    
        //设置下一个调用者
        public void setNext(Approver next) {
            this.next = next;
        }
    
        public abstract void processApprover(ApproveRequest approveRequest);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3,然后开始写一个链条中的第一个结点,由教学主任负责审批。如果金额太大,教学主任审批不了,那么就由这个院长审批

    /**
     * @Author: zhenghuisheng
     * @Date: 2022/9/11 21:19
     */
    public class DepartmentApprover extends Approver {
    	public DepartmentApprover(String name) { super(name); }
    	@Override
    	public void processRequest(ApproveRequest approveRequest) {
    		if(approveRequest.getPrice() <= 5000) {
    			System.out.println(" 请求编号 id= " + approveRequest.getId() + " 被 " + this.name + " 处理");
    		}else {
    			approver.processRequest(approveRequest);
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    4,然后开始写一个链条中的第二个结点,由院长负责审批。如果金额太大,院长审批不了,那么就由这个副校长审批

    /**
     * @Author: zhenghuisheng
     * @Date: 2022/9/11 21:19
     */
    public class CollegeApprover extends Approver {
    	public CollegeApprover(String name) {super(name); }
    	@Override
    	public void processRequest(ApproveRequest approveRequest) {
    		if(approveRequest.getPrice() < 5000 && approveRequest.getPrice() <= 10000) {
    			System.out.println(" 请求编号 id= " + approveRequest.getId() + " 被 " + this.name + " 处理");
    		}else {
    			approver.processRequest(purchaseRequest);
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    5,然后开始写一个链条中的第四个结点,由副长负责审批。

    /**
     * @Author: zhenghuisheng
     * @Date: 2022/9/11 21:18
     */
    public class SchoolMasterApprover extends Approver {
    	public SchoolMasterApprover(String name) {super(name); }
    	@Override
    	public void processRequest(ApproveRequest approveRequest) {
    		if(approveRequest.getPrice() > 30000) {
    			System.out.println(" 请求编号 id= " + approveRequest.getId() + " 被 " + this.name + " 处理");
    		}else {
    			approver.processRequest(purchaseRequest);
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    6,最后写一个测试类

    /**
     * @Author: zhenghuisheng
     * @Date: 2022/9/11 21:29
     */
    public class Test {
    	public static void main(String[] args) {
    		//创建一个请求
    		ApproveRequest approveRequest = new ApproveRequest(1, 31000, 1);
    		//创建相关的审批人
    		DepartmentApprover departmentApprover = new DepartmentApprover("张主任");
    		CollegeApprover collegeApprover = new CollegeApprover("李院长");
    		ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("王副校");
    		SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("佟校长");
    		
    		//需要将各个审批级别的下一个设置好 
    		departmentApprover.setApprover(collegeApprover);
    		collegeApprover.setApprover(viceSchoolMasterApprover);
    		viceSchoolMasterApprover.setApprover(schoolMasterApprover);
    		//单向责任链这里可以不加
    		schoolMasterApprover.setApprover(departmentApprover);
    		
    		departmentApprover.processRequest(approveRequest);
    		viceSchoolMasterApprover.processRequest(approveRequest);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    到这里为止,一个简单的责任链模式就实现好了

  • 相关阅读:
    资讯网站实时翻译软件
    壹基金爱泽瑞金 安全家园物料配送忙
    HTML5期末大作业:美妆网页主题网站设计——清新的手工肥皂网站展示(4页)HTML+CSS+JavaScript
    【C++】运算符的重载
    提高分层 SQL 结构的性能
    RabbitMQ的六种工作模式
    devops学习(三) K8环境部署jenkins
    Topaz Video AI:引领视频质量革命,让您的内容焕发新生
    Haproxy搭建 Web 群集实现负载均衡
    小白vite+vue3搭建项目整个流程
  • 原文地址:https://blog.csdn.net/zhenghuishengq/article/details/126809945