文章目录
责任链模式 (Chain of Responsibility Pattern)
责任链模式是一种 行为型设计模式,允许多个对象都有机会处理请求,而避免请求发送者与接收者的耦合。将这些对象连成一条链,并沿着链传递请求,直到有对象处理它为止。
原理
- 核心思想:
- 请求在链上传递,每个节点(处理者)都可以处理请求或将其传递给下一个节点。
- 节点(处理者)只关注自己职责范围内的请求,其余部分交给链上的下一个节点。
- 适用场景:
- 请求需要被多个对象处理。
- 处理者链的顺序需要灵活修改。
- 请求发送者和处理者之间需要解耦。
- 参与角色:
- Handler(抽象处理者):
- 定义请求处理的方法和对下一个处理者的引用。
- ConcreteHandler(具体处理者):
- 实现抽象处理者的处理逻辑。
- 根据条件决定是否处理请求或传递给下一个处理者。
- Client(客户端):
- 创建处理链并发送请求。
- Handler(抽象处理者):
优点
- 解耦:请求发送者无需关心请求的具体处理逻辑。
- 灵活性:通过改变链的结构,动态修改请求的处理流程。
- 扩展性:新增处理者非常方便,只需加入链中即可。
缺点
- 链过长:可能导致请求处理效率低下。
- 难以调试:链中处理过程可能难以追踪,尤其是动态配置的链。
- 可能无人处理:若链的末端也未处理请求,可能会导致问题。
示例代码
场景描述
以一个用户请求审批流程为例:用户提交的请求需要经过 经理、总监 和 CEO 的审批,每个审批者根据权限决定是否批准,若无法批准,则传递给链上的下一个审批者。
1. 定义处理者接口
// 抽象处理者
public abstract class Handler {
protected Handler nextHandler; // 下一个处理者
// 设置下一个处理者
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
// 抽象处理方法
public abstract void handleRequest(int amount);
}
2. 实现具体处理者
// 经理处理者
public class ManagerHandler extends Handler {
@Override
public void handleRequest(int amount) {
if (amount <= 1000) {
System.out.println("Manager approved request of $" + amount);
} else if (nextHandler != null) {
nextHandler.handleRequest(amount);
}
}
}
// 总监处理者
public class DirectorHandler extends Handler {
@Override
public void handleRequest(int amount) {
if (amount <= 5000) {
System.out.println("Director approved request of $" + amount);
} else if (nextHandler != null) {
nextHandler.handleRequest(amount);
}
}
}
// CEO处理者
public class CEOHandler extends Handler {
@Override
public void handleRequest(int amount) {
if (amount > 5000) {
System.out.println("CEO approved request of $" + amount);
} else if (nextHandler != null) {
nextHandler.handleRequest(amount);
}
}
}
3. 客户端代码
public class ChainOfResponsibilityExample {
public static void main(String[] args) {
// 创建处理者
Handler manager = new ManagerHandler();
Handler director = new DirectorHandler();
Handler ceo = new CEOHandler();
// 构建责任链
manager.setNextHandler(director);
director.setNextHandler(ceo);
// 测试请求
int[] requests = {500, 2000, 8000};
for (int amount : requests) {
System.out.println("Requesting $" + amount);
manager.handleRequest(amount);
System.out.println();
}
}
}
输出结果
Requesting $500
Manager approved request of $500
Requesting $2000
Director approved request of $2000
Requesting $8000
CEO approved request of $8000
UML 类图
+-----------------+
| Handler |
+-----------------+
| - nextHandler |
| + setNextHandler() |
| + handleRequest() |
+-----------------+
^
|
+------------------+ +------------------+ +------------------+
| ManagerHandler | | DirectorHandler | | CEOHandler |
+------------------+ +------------------+ +------------------+
| + handleRequest()| | + handleRequest()| | + handleRequest()|
+------------------+ +------------------+ +------------------+
使用场景
- 权限审批系统:如请假、报销等审批流程。
- 日志处理:不同级别的日志交由不同的处理器处理。
- 过滤链:如 Web 服务器中的请求过滤器链。
优化与扩展
- 链的动态配置:
- 使用配置文件或依赖注入工具动态构建责任链。
- 链的短路机制:
- 提供一个终止标志,避免链无意义地传递。
- 结合其他模式:
- 与 装饰器模式 结合,增强处理者的功能。
小结
- 责任链模式解耦了请求的发送和处理过程,提供了一种灵活的责任分配机制。
- 它的主要特点是链式传递和逐步处理,适用于流程化的处理需求。
- 在实现时需注意链的长度和请求未被处理的风险。