Java 编程之责任链模式

发布于:2025-06-27 ⋅ 阅读:(18) ⋅ 点赞:(0)

一、什么是责任链模式?

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

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

二、责任链例子

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

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

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

三、UML结构图

在这里插入图片描述
在这里插入图片描述

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

四、代码实现

抽象处理者

构建一个抽象的 Handler类。

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

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

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

具体处理者

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

// 班组长处理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);
        }
    }
}
// 主管处理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);
        }
    }
}
// 部门经理处理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);
        }
    }
}
// 总经理处理所有请假
public class GeneralManager extends Handler {
    @Override
    public void handleRequest(int leaveDays) {
        System.out.println("总经理批准了" + leaveDays + "天的请假");
    }
}

构建责任链

客户端调用。

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("------");
        }
    }
}

具体输出

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

五、链式构建器

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

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

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

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

六、责任链模式的优缺点

优点:

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

缺点:

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

七、实际应用场景

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

八、小结

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

九、参考

《23种设计模式概览》
在这里插入图片描述

@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



网站公告

今日签到

点亮在社区的每一天
去签到