设计模式之责任链模式,-员工请假审批系统

一、概述

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它通过将请求的发送者和接收者解耦,使多个对象都有机会处理这个请求。这些处理者对象被连接成一条链,请求沿着这条链传递,直到有一个对象处理它为止。

核心思想

  1. 解耦:将请求的发送者和接收者解耦

  2. 灵活性:可以动态地重新组织和分配责任

  3. 多处理者:允许多个对象处理同一个请求

适用场景

  • 有多个对象可以处理同一个请求,但具体由哪个对象处理需要在运行时决定

  • 需要在不明确指定接收者的情况下,向多个对象中的一个提交请求

  • 可动态指定一组对象处理请求

二、责任链模式结构

责任链模式主要包含以下几个角色:

  1. Handler(抽象处理者):定义处理请求的接口,通常包含一个处理请求的方法和一个设置后继者的方法

  2. ConcreteHandler(具体处理者):实现抽象处理者的处理方法,判断是否有能力处理该请求,如果可以则处理,否则将请求转发给后继者

  3. Client(客户端):创建处理链,并向链头的具体处理者对象提交请求

三、员工请假审批系统

假设我们有一个员工请假审批系统,不同级别的领导有不同的审批权限:

  • 组长:可审批1天以内的假期

  • 经理:可审批3天以内的假期

  • 总监:可审批7天以内的假期

  • 超过7天需要CEO审批

1. 定义抽象处理者
public abstract class LeaveHandler {
    protected LeaveHandler nextHandler;
    
    // 设置下一个处理者
    public void setNextHandler(LeaveHandler handler) {
        this.nextHandler = handler;
    }
    
    // 处理请假请求
    public abstract void handleRequest(LeaveRequest request);
}
2. 定义请假请求类
public class LeaveRequest {
    private String employeeName;
    private int leaveDays;
    
    public LeaveRequest(String employeeName, int leaveDays) {
        this.employeeName = employeeName;
        this.leaveDays = leaveDays;
    }
    
    // getter方法
    public String getEmployeeName() {
        return employeeName;
    }
    
    public int getLeaveDays() {
        return leaveDays;
    }
}
3. 实现具体处理者

组长处理者

public class GroupLeader extends LeaveHandler {
    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getLeaveDays() <= 1) {
            System.out.println("组长批准" + request.getEmployeeName() + "请假" + request.getLeaveDays() + "天");
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(request);
            }
        }
    }
}

经理处理者

public class Manager extends LeaveHandler {
    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getLeaveDays() <= 3) {
            System.out.println("经理批准" + request.getEmployeeName() + "请假" + request.getLeaveDays() + "天");
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(request);
            }
        }
    }
}

总监处理者

public class Director extends LeaveHandler {
    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getLeaveDays() <= 7) {
            System.out.println("总监批准" + request.getEmployeeName() + "请假" + request.getLeaveDays() + "天");
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(request);
            }
        }
    }
}

CEO处理者

public class CEO extends LeaveHandler {
    @Override
    public void handleRequest(LeaveRequest request) {
        System.out.println("CEO批准" + request.getEmployeeName() + "请假" + request.getLeaveDays() + "天");
    }
}
测试类

public class LeaveSystemTest {
    public static void main(String[] args) {
        // 创建处理者
        LeaveHandler groupLeader = new GroupLeader();
        LeaveHandler manager = new Manager();
        LeaveHandler director = new Director();
        LeaveHandler ceo = new CEO();
        
        // 设置责任链
        groupLeader.setNextHandler(manager);
        manager.setNextHandler(director);
        director.setNextHandler(ceo);
        
        // 创建请假请求
        LeaveRequest request1 = new LeaveRequest("张三", 1);
        LeaveRequest request2 = new LeaveRequest("李四", 4);
        LeaveRequest request3 = new LeaveRequest("王五", 8);
        
        // 提交请求
        groupLeader.handleRequest(request1);
        groupLeader.handleRequest(request2);
        groupLeader.handleRequest(request3);
    }
}
5. 输出结果

四、责任链模式变体

1. 纯与不纯的责任链模式

  • 纯责任链模式:请求必须被某个处理者处理,不允许未被处理的情况

  • 不纯责任链模式:请求可以被部分处理或不被任何处理者处理

2. 功能增强

可以在抽象处理者中添加更多方法,如:

// 判断是否能处理请求
protected abstract boolean canHandle(LeaveRequest request);

// 处理请求的具体逻辑
protected abstract void doHandle(LeaveRequest request);

五、责任链模式优缺点

优点

  1. 降低耦合度:请求发送者不需要知道具体由哪个处理者处理

  2. 增强灵活性:可以动态增加或修改处理链

  3. 简化对象:每个处理者只需关注自己责任范围内的请求

缺点

  1. 请求可能未被处理:如果没有配置默认处理者,请求可能到达链尾仍未被处理

  2. 性能问题:请求可能需要遍历整个链才能被处理

  3. 调试困难:请求的传递是隐式的,调试时不易跟踪

六、实际应用场景

  1. Java Servlet中的Filter:多个Filter组成一个链,依次处理请求

  2. Spring Security的认证流程:多个AuthenticationProvider组成认证链

  3. 日志系统中的多级日志处理:DEBUG → INFO → WARN → ERROR

  4. 异常处理:多层try-catch块可以看作责任链的一种形式

七、与其他模式的关系

  1. 与命令模式:责任链模式可以配合命令模式使用,将请求封装为命令对象

  2. 与组合模式:可以用组合模式来构建树形结构的责任链

  3. 与装饰器模式:两者都基于递归组合,但目的不同。装饰器模式是动态添加功能,责任链模式是传递请求

责任链模式通过将请求和处理分离,实现了请求发送者和接收者的解耦,提高了系统的灵活性。在实际开发中,合理使用责任链模式可以使代码更加清晰、易于维护和扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值