责任链模式
介绍
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象处理同一个请求,而客户端不必知道哪个对象最终会处理该请求。请求沿着一条链传递,直到有一个对象处理它为止。
原理
责任链模式的核心原理包括:
- 抽象处理者:定义处理请求的接口,包含一个指向下一个处理者的引用
- 具体处理者:实现抽象处理者的接口,决定是否处理请求,如果不处理则传递给下一个处理者
- 客户端:创建处理链,并向链的第一个处理者提交请求
图示
责任链模式的核心结构包括抽象处理者、具体处理者和客户端。以下是责任链模式的UML类图和工作流程图示:
UML类图
+----------------+ +----------------+
| Handler |<----| Client |
+----------------+ +----------------+
| - nextHandler | | + main() |
| + setNextHandler()| | |
| + handleRequest()| | |
+-------^--------+ +----------------+
|
|
+-------+--------+ +-------------+ +-------------+
| ConcreteHandlerA|-->|ConcreteHandlerB|-->|ConcreteHandlerC|
+----------------+ +-------------+ +-------------+
| + handleRequest()| | + handleRequest()| | + handleRequest()|
+----------------+ +-------------+ +-------------+
工作流程图
Client
|
v
+----------------+ 处理请求? +----------------+
| ConcreteHandlerA|------------>| ConcreteHandlerB|
+----------------+ 否 +----------------+
| 是 | 否
v v
处理请求并返回 +----------------+
| ConcreteHandlerC|
+----------------+
| 否
v
无处理者,返回错误
执行流程示例
请求 5 → ConcreteHandlerA (处理)
请求 15 → ConcreteHandlerA → ConcreteHandlerB (处理)
请求 25 → ConcreteHandlerA → ConcreteHandlerB → ConcreteHandlerC (处理)
请求 35 → ConcreteHandlerA → ConcreteHandlerB → ConcreteHandlerC → 无处理者 (错误)
代码示例
抽象处理者
public abstract class Handler {
protected Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handleRequest(int request);
}
具体处理者
public class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 0 && request < 10) {
System.out.println("处理者A处理请求 " + request);
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
} else {
System.out.println("没有处理者能处理请求 " + request);
}
}
}
public class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println("处理者B处理请求 " + request);
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
} else {
System.out.println("没有处理者能处理请求 " + request);
}
}
}
public class ConcreteHandlerC extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 20 && request < 30) {
System.out.println("处理者C处理请求 " + request);
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
} else {
System.out.println("没有处理者能处理请求 " + request);
}
}
}
客户端代码
public class Client {
public static void main(String[] args) {
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
Handler handlerC = new ConcreteHandlerC();
// 设置责任链
handlerA.setNextHandler(handlerB);
handlerB.setNextHandler(handlerC);
// 提交请求
handlerA.handleRequest(5);
handlerA.handleRequest(15);
handlerA.handleRequest(25);
handlerA.handleRequest(35);
}
}
解决方案
应用场景
- 请求处理流程:如HTTP请求处理、日志级别处理
- 异常处理:不同级别的异常由不同的处理器处理
- 审批流程:如请假审批、报销审批
- 事件传播:UI事件的冒泡和捕获
- 过滤器链:如Web中的过滤器
最佳实践
- 保持处理者简洁:每个处理者只处理一类请求
- 避免过长的责任链:过长的责任链会导致性能问题和调试困难
- 设置默认处理者:确保每个请求都能被处理
- 使用工厂模式创建责任链:结合工厂模式管理责任链的创建
- 考虑使用注解或配置文件:在大型应用中,通过注解或配置文件定义责任链
优缺点
优点:
- 解耦请求发送者和接收者
- 灵活性高,可以动态组合处理者
- 符合开闭原则
- 易于扩展新的处理者
缺点:
- 请求可能不被处理
- 责任链过长会影响性能
- 调试困难,难以跟踪请求的处理过程
工具推荐
- Spring Framework:提供HandlerInterceptor接口实现责任链模式
- Java Servlet API:Filter接口基于责任链模式
- Apache Commons Chain:专门实现责任链模式的库
- Netty:ChannelHandlerContext实现责任链模式
- RxJava/RxAndroid:提供操作符实现链式调用