聊一聊:设计模式——责任链模式

0 阅读4分钟

你好,我是风一样的树懒,一个工作十多年的后端专家,曾就职京东、阿里等多家互联网头部企业。公众号“吴计可师”,已经更新了近百篇高质量的面试相关文章,喜欢的朋友欢迎关注点赞

责任链模式详解


一、定义与核心思想

责任链模式(Chain of Responsibility) 是一种行为型设计模式,通过将多个处理对象连成一条链,允许请求沿着链传递直至被处理。核心思想是解耦请求发送者与接收者,让多个对象都有机会处理请求,避免请求者与处理者的显式耦合。


二、适用场景

  1. 多级审批流程:如请假申请需经组长→经理→CEO逐级审批。
  2. 请求过滤链:如Web请求的鉴权→日志→压缩处理。
  3. 异常处理机制:多个处理器尝试解决同一问题(如错误重试策略)。
  4. 动态可扩展处理:运行时灵活调整处理顺序或增减处理器。

三、模式结构

角色职责
处理者(Handler)定义处理请求的接口,持有下一个处理者的引用(如Approver)。
具体处理者(Concrete Handler)实现处理逻辑,决定是否处理请求或传递给下一节点(如GroupLeaderManager)。
客户端(Client)初始化责任链并触发请求(如提交审批申请)。

四、实现示例:请假审批系统

// 请求对象
public class LeaveRequest {
    private String employee;
    private int days;

    public LeaveRequest(String employee, int days) {
        this.employee = employee;
        this.days = days;
    }
    // Getter方法...
}

// 处理者接口
public abstract class Approver {
    protected Approver nextApprover;

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

    public abstract void handleRequest(LeaveRequest request);
}

// 具体处理者:组长
public class GroupLeader extends Approver {
    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getDays() <= 2) {
            System.out.println("组长批准" + request.getEmployee() + "请假" + request.getDays() + "天");
        } else if (nextApprover != null) {
            nextApprover.handleRequest(request);
        }
    }
}

// 具体处理者:经理
public class Manager extends Approver {
    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getDays() <= 5) {
            System.out.println("经理批准" + request.getEmployee() + "请假" + request.getDays() + "天");
        } else if (nextApprover != null) {
            nextApprover.handleRequest(request);
        }
    }
}

// 具体处理者:CEO
public class CEO extends Approver {
    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getDays() <= 10) {
            System.out.println("CEO批准" + request.getEmployee() + "请假" + request.getDays() + "天");
        } else {
            System.out.println("请假天数过长,无法批准");
        }
    }
}

// 客户端构建责任链
Approver groupLeader = new GroupLeader();
Approver manager = new Manager();
Approver ceo = new CEO();

groupLeader.setNext(manager);
manager.setNext(ceo);

// 提交请求
groupLeader.handleRequest(new LeaveRequest("张三", 1));  // 组长处理
groupLeader.handleRequest(new LeaveRequest("李四", 4));  // 经理处理
groupLeader.handleRequest(new LeaveRequest("王五", 8));  // CEO处理
groupLeader.handleRequest(new LeaveRequest("赵六", 15)); // 拒绝

五、核心优势

  1. 解耦请求与处理:发送者无需知道具体处理者。
  2. 动态链式扩展:新增处理者或调整顺序无需修改已有代码。
  3. 灵活责任分配:各处理者专注自身职责范围。

六、应用案例

  1. Java Servlet Filter:请求经过多个过滤器处理。
  2. Spring Security:认证与授权责任链。
  3. 日志框架:日志信息按级别传递(DEBUG → INFO → ERROR)。
  4. 游戏事件处理:技能效果触发链(伤害计算→状态附加→动画播放)。

七、模式变体

1. 纯责任链:请求必须被某个处理者处理(如审批必须给出结果)。

public void handleRequest(Request request) {
    if (canHandle(request)) {
        // 处理请求
    } else if (next != null) {
        next.handleRequest(request);
    } else {
        throw new UnhandledRequestException();
    }
}

2. 功能叠加链:所有处理者依次处理请求(如管道过滤器)。

public void handleRequest(Request request) {
    preProcess(request);    // 前置处理
    if (next != null) {
        next.handleRequest(request);
    }
    postProcess(request);   // 后置处理
}

八、注意事项

  1. 链的完整性:确保请求最终被处理(可设置默认处理器)。
  2. 性能优化:避免长链遍历(如缓存处理节点)。
  3. 循环引用检测:防止处理链成环导致无限递归。

九、与其他模式对比

模式核心差异
命令模式封装请求为对象,责任链传递请求至处理器。
装饰器模式动态添加功能,责任链动态选择处理器。
策略模式选择单一算法,责任链可能触发多个处理。

十、最佳实践

  1. 链式构建工具:提供链式API简化配置。

    public class ChainBuilder {
        private Approver head;
        private Approver tail;
    
        public ChainBuilder addHandler(Approver handler) {
            if (head == null) {
                head = tail = handler;
            } else {
                tail.setNext(handler);
                tail = handler;
            }
            return this;
        }
    
        public Approver build() {
            return head;
        }
    }
    
    // 使用
    Approver chain = new ChainBuilder()
        .addHandler(new GroupLeader())
        .addHandler(new Manager())
        .addHandler(new CEO())
        .build();
    
  2. 组合模式融合:处理链本身可作为复合处理器。

  3. 异步责任链:适用于非阻塞处理场景(如消息队列消费)。


总结

责任链模式通过链式传递机制,为多级处理逻辑提供了灵活、可扩展的解决方案。在需要动态调整处理流程或解耦请求与处理的场景中,该模式能显著提升代码的可维护性,是处理复杂业务逻辑的利器。

今天文章就分享到这儿,喜欢的朋友可以关注我的公众号,回复“进群”,可进免费技术交流群。博主不定时回复大家的问题。 公众号:吴计可师

qrcode_for_gh_79f35896a87f_258.jpg