自学教程 学编程从这里开始

责任链模式

《责任链模式》|设计模式系列第14篇

系列:行为型模式 · 责任链模式(Chain of Responsibility Pattern)
关键词:请求传递、链式处理器、解耦发送者与接收者、逐级处理

一、什么是责任链模式

责任链模式(Chain of Responsibility Pattern):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

属于行为型设计模式。

简单理解:
把多个处理器串联成一条链条。请求从链头开始依次传递,每个处理器判断自己是否可以处理该请求:可以处理就执行逻辑;不能处理则交给链上下一个处理器。发送请求的客户端不需要知道谁最终处理请求,也不需要知道链条结构。
例子:审批流。员工申请请假,先由直属主管审批,额度不够则流转到部门经理,再到总经理。

核心意图
解耦请求发起方与请求处理方;多个处理器有机会处理请求,动态调整处理器顺序。

适用场景

  1. 一个请求需要经过多个处理器依次判断处理
  2. 处理器的处理规则和顺序需要动态调整
  3. 客户端不需要关心请求由谁处理
  4. 审批、过滤器、拦截器、日志处理流水线

⚠️ 缺点预警:请求可能在链条尾部未被处理,需要兜底;链条过长会影响性能;调试链路比较麻烦。

二、UML结构图

角色划分:

  1. Handler(抽象处理者):定义处理请求接口,持有下一个处理器引用
  2. ConcreteHandler(具体处理者):实现处理逻辑,判断是否处理请求;无法处理则转发给下一个Handler
  3. Client(客户端):组装责任链,发起请求

三、Java 完整示例

场景:LeaveApproval 请假审批。

  • Supervisor:审批3天以内假期
  • Manager:审批3~7天假期
  • CEO:审批7天以上假期

    代码全部使用英文。

1. Handler 抽象处理者

public abstract class Approver {
    protected Approver nextApprover;

    public void setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }

    public abstract void approve(int leaveDays);
}

2. ConcreteHandler 具体处理者

public class Supervisor extends Approver {
    @Override
    public void approve(int leaveDays) {
        if (leaveDays <= 3) {
            System.out.println("Supervisor approved leave days: " + leaveDays);
        } else if (nextApprover != null) {
            nextApprover.approve(leaveDays);
        } else {
            System.out.println("No approver can handle this request");
        }
    }
}

public class Manager extends Approver {
    @Override
    public void approve(int leaveDays) {
        if (leaveDays > 3 && leaveDays <= 7) {
            System.out.println("Manager approved leave days: " + leaveDays);
        } else if (nextApprover != null) {
            nextApprover.approve(leaveDays);
        } else {
            System.out.println("No approver can handle this request");
        }
    }
}

public class CEO extends Approver {
    @Override
    public void approve(int leaveDays) {
        if (leaveDays > 7) {
            System.out.println("CEO approved leave days: " + leaveDays);
        } else if (nextApprover != null) {
            nextApprover.approve(leaveDays);
        } else {
            System.out.println("No approver can handle this request");
        }
    }
}

3. Client 客户端

public class Client {
    public static void main(String[] args) {
        Approver supervisor = new Supervisor();
        Approver manager = new Manager();
        Approver ceo = new CEO();

        // build chain
        supervisor.setNextApprover(manager);
        manager.setNextApprover(ceo);

        supervisor.approve(2);
        supervisor.approve(5);
        supervisor.approve(10);
    }
}

运行输出:

Supervisor approved leave days: 2
Manager approved leave days: 5
CEO approved leave days: 10

四、优缺点总结

✅ 优点

  1. 解耦请求发起者与处理者,客户端不用关心处理细节
  2. 处理器可以动态新增、删除、调整顺序,灵活修改链条
  3. 单一职责,每个处理器只负责自己范围内的逻辑

❌ 缺点

  1. 请求没有保证一定被处理,需要兜底逻辑
  2. 链条过长时,请求逐层传递,性能下降
  3. 调试链路追踪困难

五、框架源码应用

  • Servlet Filter 过滤器链
  • Spring Interceptor 拦截器链
  • Spring Security FilterChain
  • MyBatis Plugin 拦截器链

六、小结

责任链核心:请求沿着处理器链条传递,每个处理器判断是否处理,无法处理则转发。
适合多级审批、过滤器、拦截器场景;可以灵活增删处理器,但是要控制链条长度,并且做好兜底。

标签:

0 条笔记