设计模式9-责任链模式

定义

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

优势

  • 解耦请求发送者与接收者,发送者无需知道具体由哪个对象处理请求;

  • 新增处理者时只需加入链条,无需修改原有代码,符合 "开闭原则"。

场景

生活场景

最典型的例子是 公司请假审批流程:

  • 请假 1 天以内:组长直接审批;

  • 请假 1-3 天:组长无权处理,传递给部门经理审批;

  • 请假 3 天以上:部门经理无权处理,传递给总经理审批。

这里,组长→部门经理→总经理形成一条 "责任链",请假请求会沿着链条传递,直到被对应的负责人处理。

Java 中的责任链场景

  1. Servlet Filter 链:

    客户端请求经过多个 Filter(过滤器)处理(如编码过滤、权限校验、日志记录等),每个 Filter 可选择处理请求后传递给下一个 Filter,或直接终止请求。

  2. Spring Interceptor 链:

    Spring MVC 中的拦截器链,对请求进行预处理(如登录验证)、后处理(如数据封装),每个 Interceptor 可决定是否继续传递请求。

  3. 异常处理机制:

    Java 的异常捕获(try-catch)本质上也是责任链:异常会从发生处向上传递,直到被第一个匹配的 catch 块处理。

代码

java 复制代码
// 抽象审批者类:定义责任链节点的通用行为
abstract class Approver {
    protected Approver nextApprover; // 下一个审批者(责任链的下一个节点)

    // 设置下一个审批者
    public void setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }

    // 抽象处理方法:子类需实现具体审批逻辑
    public abstract void handleRequest(LeaveRequest request);
}


// 请假请求类:封装请求信息
 class LeaveRequest {
    private String name; // 申请人姓名
    private int days; // 请假天数

    public LeaveRequest(String name, int days) {
        this.name = name;
        this.days = days;
    }

    // getter方法
    public String getName() {
        return name;
    }

    public int getDays() {
        return days;
    }
}

// 组长:处理1天以内的请假
 class GroupLeader extends Approver {
    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getDays() <= 1) {
            System.out.println("组长批准 " + request.getName() + " 请假" + request.getDays() + "天");
        } else {
            // 超过权限,传递给下一个审批者
            if (nextApprover != null) {
                nextApprover.handleRequest(request);
            }
        }
    }
}

// 总经理:处理3天以上的请假
class GeneralManager extends Approver {
    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getDays() > 3) {
            System.out.println("总经理批准 " + request.getName() + " 请假" + request.getDays() + "天");
        } else {
            // 超过权限,传递给下一个审批者(此处为链的终点,可省略)
            if (nextApprover != null) {
                nextApprover.handleRequest(request);
            }
        }
    }
}

// 部门经理:处理1-3天的请假
 class DeptManager extends Approver {
    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getDays() > 1 && request.getDays() <= 3) {
            System.out.println("部门经理批准 " + request.getName() + " 请假" + request.getDays() + "天");
        } else {
            // 超过权限,传递给下一个审批者
            if (nextApprover != null) {
                nextApprover.handleRequest(request);
            }
        }
    }
}

// 测试类:构建责任链并模拟请假请求
class Client {
    public static void main(String[] args) {
        // 创建审批者
        Approver groupLeader = new GroupLeader();
        Approver deptManager = new DeptManager();
        Approver generalManager = new GeneralManager();

        // 构建责任链:组长→部门经理→总经理
        groupLeader.setNextApprover(deptManager);
        deptManager.setNextApprover(generalManager);

        // 模拟请假请求
        LeaveRequest request1 = new LeaveRequest("张三", 1); // 1天:组长处理
        LeaveRequest request2 = new LeaveRequest("李四", 2); // 2天:部门经理处理
        LeaveRequest request3 = new LeaveRequest("王五", 5); // 5天:总经理处理

        // 发送请求(从链的起点开始)
        groupLeader.handleRequest(request1);
        groupLeader.handleRequest(request2);
        groupLeader.handleRequest(request3);
    }
}

责任链模式代码

相关推荐
UrSpecial6 小时前
设计模式:责任链模式
设计模式·责任链模式
我们从未走散2 天前
设计模式学习笔记-----抽象责任链模式
java·笔记·学习·设计模式·责任链模式
西红柿维生素3 天前
设计模式之责任链模式
设计模式·责任链模式
左灯右行的爱情6 天前
深度学习设计模式:责任链(Chain of Responsibility)模式(例子+业务场景+八股)
深度学习·设计模式·责任链模式
IT小白架构师之路17 天前
常用设计模式系列(十八)-责任链模式
设计模式·责任链模式
永卿0011 个月前
设计模式-责任链模式
java·设计模式·责任链模式
hello 早上好1 个月前
深入解析AOP调用链:递归与责任链模式的协同实现
java·责任链模式
先鱼鲨生1 个月前
【Linux】System V - 责任链模式与消息队列
linux·责任链模式
搜狐技术产品小编20231 个月前
浅析责任链模式在视频审核场景中的应用
java·开发语言·责任链模式