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
相关推荐
Scott9999HH2 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔2 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社3 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海3 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖4 小时前
JDK 26 新特性详解
java·开发语言
马优晨5 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区6 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大7 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai7 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说7 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json