Java 编程之责任链模式

一、什么是责任链模式?

责任链模式(Chain of Responsibility Pattern) 是一种行为型设计模式,它让多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,沿着这条链传递请求,直到有对象处理它为止。一般用在如下的场景

  • 多个对象可以处理同一个请求,但具体由哪个处理方未确定;
  • 系统需动态指定处理者;
  • 想在运行时灵活地添加新的处理节点;
    可能比较抽象,今天本篇就以例子的方式,让你快速理解到这些文字描述。

二、责任链例子

小张想请假,走公司流程:

复制代码
小张 → 班组长 → 主管 → 部门经理 → 总经理
  • 小张请 1 天假,班组长就能批;
  • 请 3 天假,需要主管审批;
  • 请 7 天,得上总经理签字。

这就是责任链 流程。谁能处理就在哪停下,不能处理就往上交

三、UML结构图

在这里插入图片描述

  • Handler 定义处理请求的接口;
  • 每个 Leader 具体处理不同级别的请求;
  • 请求不能处理时,传给下一个节点。

四、代码实现

抽象处理者

构建一个抽象的 Handler类。

java 复制代码
// 抽象类,定义处理逻辑和下一个节点
public abstract class Handler {
    protected Handler next;

    public void setNext(Handler next) {
        this.next = next;
    }

    // 处理请求的方法
    public abstract void handleRequest(int leaveDays);
}

具体处理者

具体处理审批十各级审批人。

java 复制代码
// 班组长处理1天以内的请假
public class TeamLeader extends Handler {
    @Override
    public void handleRequest(int leaveDays) {
        if (leaveDays <= 1) {
            System.out.println("班组长批准了" + leaveDays + "天的请假");
        } else if (next != null) {
            System.out.println("班组长无权处理,转交主管");
            next.handleRequest(leaveDays);
        }
    }
}
java 复制代码
// 主管处理3天以内的请假
public class Supervisor extends Handler {
    @Override
    public void handleRequest(int leaveDays) {
        if (leaveDays <= 3) {
            System.out.println("主管批准了" + leaveDays + "天的请假");
        } else if (next != null) {
            System.out.println("主管无权处理,转交经理");
            next.handleRequest(leaveDays);
        }
    }
}
java 复制代码
// 部门经理处理7天以内的请假
public class Manager extends Handler {
    @Override
    public void handleRequest(int leaveDays) {
        if (leaveDays <= 7) {
            System.out.println("经理批准了" + leaveDays + "天的请假");
        } else if (next != null) {
            System.out.println("经理无权处理,转交总经理");
            next.handleRequest(leaveDays);
        }
    }
}
java 复制代码
// 总经理处理所有请假
public class GeneralManager extends Handler {
    @Override
    public void handleRequest(int leaveDays) {
        System.out.println("总经理批准了" + leaveDays + "天的请假");
    }
}

构建责任链

客户端调用。

java 复制代码
public class Client {
    public static void main(String[] args) {
        // 构建链条:组长 → 主管 → 经理 → 总经理
        Handler leader = new TeamLeader();
        Handler supervisor = new Supervisor();
        Handler manager = new Manager();
        Handler generalManager = new GeneralManager();

        leader.setNext(supervisor);
        supervisor.setNext(manager);
        manager.setNext(generalManager);

        // 发起请求
        int[] testLeaves = {1, 2, 5, 10};

        for (int days : testLeaves) {
            System.out.println("申请" + days + "天请假:");
            leader.handleRequest(days);
            System.out.println("------");
        }
    }
}

具体输出

plaintext 复制代码
申请1天请假:
班组长批准了1天的请假
------
申请2天请假:
班组长无权处理,转交主管
主管批准了2天的请假
------
申请5天请假:
班组长无权处理,转交主管
主管无权处理,转交经理
经理批准了5天的请假
------
申请10天请假:
班组长无权处理,转交主管
主管无权处理,转交经理
经理无权处理,转交总经理
总经理批准了10天的请假
------

五、链式构建器

责任链的高级写法,可以使用链式调用简化链条搭建:

java 复制代码
leader.setNext(supervisor).setNext(manager).setNext(generalManager);

为此只需修改 setNext() 方法返回值:

java 复制代码
public Handler setNext(Handler next) {
    this.next = next;
    return next;
}

六、责任链模式的优缺点

优点:

  • 解耦请求发送者和处理者
  • 动态组合链条结构,扩展性强
  • 处理流程清晰,符合现实逻辑

缺点:

  • 可能造成请求无人处理
  • 每个处理节点都必须处理转发逻辑

七、实际应用场景

应用场景 描述
Servlet Filter链 请求在多个Filter间传递
Spring Security拦截链 多个拦截器处理登录/权限
日志记录 日志可传给不同的输出设备
OA审批流程 按审批等级处理请假/报销等

八、小结

责任链模式是非常贴近现实的模式之一,很多审批、拦截、处理流程都可以用它来建模。它解耦了处理者与请求者,使系统更灵活、可拓展。掌握此模式,是 Java 工程师进阶之路的重要一环。

九、参考

《23种设计模式概览》

PlantUML 复制代码
@startuml
title Java责任链模式结构图(Handler责任链)

abstract class Handler {
    +setNext(next: Handler)
    +handleRequest(request)
    -next: Handler
}

class LeaderA {
    班组长
}
class LeaderB {
    部门主管
}
class LeaderC {
    总经理
}
class LeaderN {
    
    可以加更多节点
    ......
}

Handler <|-- LeaderA
Handler <|-- LeaderB
Handler <|-- LeaderC

Handler <|-- "LeaderN"

@enduml
相关推荐
OpenC++7 分钟前
【C++】观察者模式
c++·观察者模式·设计模式
Naiva11 分钟前
【小技巧】Python + PyCharm 小智AI配置MCP接入点使用说明(内测)( PyInstaller打包成 .exe 可执行文件)
开发语言·python·pycharm
云动雨颤15 分钟前
Java并发性能优化|读写锁与互斥锁解析
java
梦子要转行20 分钟前
matlab/Simulink-全套50个汽车性能建模与仿真源码模型9
开发语言·matlab·汽车
ldj202028 分钟前
Centos 安装Jenkins
java·linux
hqxstudying35 分钟前
Intellij IDEA中Maven的使用
java·maven·intellij-idea
SimonKing38 分钟前
拯救大文件上传:一文彻底彻底搞懂秒传、断点续传以及分片上传
java·后端·架构
深栈解码38 分钟前
JUC并发编程 内存布局和对象头
java·后端
北方有星辰zz1 小时前
数据结构:栈
java·开发语言·数据结构
Seven971 小时前
一个static关键字引发的线上故障:深度剖析静态变量与配置热更新的陷阱
java