你好,我是风一样的树懒,一个工作十多年的后端专家,曾就职京东、阿里等多家互联网头部企业。公众号“吴计可师”,已经更新了近百篇高质量的面试相关文章,喜欢的朋友欢迎关注点赞
责任链模式详解
一、定义与核心思想
责任链模式(Chain of Responsibility) 是一种行为型设计模式,通过将多个处理对象连成一条链,允许请求沿着链传递直至被处理。核心思想是解耦请求发送者与接收者,让多个对象都有机会处理请求,避免请求者与处理者的显式耦合。
二、适用场景
- 多级审批流程:如请假申请需经组长→经理→CEO逐级审批。
- 请求过滤链:如Web请求的鉴权→日志→压缩处理。
- 异常处理机制:多个处理器尝试解决同一问题(如错误重试策略)。
- 动态可扩展处理:运行时灵活调整处理顺序或增减处理器。
三、模式结构
角色 | 职责 |
---|---|
处理者(Handler) | 定义处理请求的接口,持有下一个处理者的引用(如Approver )。 |
具体处理者(Concrete Handler) | 实现处理逻辑,决定是否处理请求或传递给下一节点(如GroupLeader 、Manager )。 |
客户端(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)); // 拒绝
五、核心优势
- 解耦请求与处理:发送者无需知道具体处理者。
- 动态链式扩展:新增处理者或调整顺序无需修改已有代码。
- 灵活责任分配:各处理者专注自身职责范围。
六、应用案例
- Java Servlet Filter:请求经过多个过滤器处理。
- Spring Security:认证与授权责任链。
- 日志框架:日志信息按级别传递(DEBUG → INFO → ERROR)。
- 游戏事件处理:技能效果触发链(伤害计算→状态附加→动画播放)。
七、模式变体
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); // 后置处理
}
八、注意事项
- 链的完整性:确保请求最终被处理(可设置默认处理器)。
- 性能优化:避免长链遍历(如缓存处理节点)。
- 循环引用检测:防止处理链成环导致无限递归。
九、与其他模式对比
模式 | 核心差异 |
---|---|
命令模式 | 封装请求为对象,责任链传递请求至处理器。 |
装饰器模式 | 动态添加功能,责任链动态选择处理器。 |
策略模式 | 选择单一算法,责任链可能触发多个处理。 |
十、最佳实践
-
链式构建工具:提供链式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();
-
组合模式融合:处理链本身可作为复合处理器。
-
异步责任链:适用于非阻塞处理场景(如消息队列消费)。
总结
责任链模式通过链式传递机制,为多级处理逻辑提供了灵活、可扩展的解决方案。在需要动态调整处理流程或解耦请求与处理的场景中,该模式能显著提升代码的可维护性,是处理复杂业务逻辑的利器。
今天文章就分享到这儿,喜欢的朋友可以关注我的公众号,回复“进群”,可进免费技术交流群。博主不定时回复大家的问题。 公众号:吴计可师