文章目录
隐藏
责任链模式(Chain of Responsibility Pattern) 是一种行为型设计模式,它通过将多个处理器(Handler)按顺序连接起来,使请求沿着链条传递,直到被某个处理器处理或到达链尾。每个处理器只关心自己能处理的部分,无法处理的请求则传递给下一个处理器。责任链模式的核心思想是解耦请求发送者和请求处理者,使得请求的发送方不必知道具体的处理逻辑。
1. 责任链模式的结构
责任链模式通常包括以下几个核心角色:
- 抽象处理者(Handler):定义了处理请求的接口或抽象类,通常包含一个
handleRequest()
方法和一个指向下一个处理者的引用。 - 具体处理者(Concrete Handler):实现
Handler
的接口或继承Handler
抽象类,负责处理特定类型的请求。每个具体处理者都包含一个对下一个处理者的引用,当无法处理请求时,将请求传递给下一个处理者。 - 客户端(Client):创建具体的处理者,并将它们按顺序链接起来,形成责任链。客户端将请求提交到责任链的起点,之后请求沿着链条传递,直到被处理或到达链尾。
责任链模式的 UML 类图
plaintextCopy code+----------------+ +-------------------------+
| Client |----->| Handler |
+----------------+ +-------------------------+
|+ handleRequest() |
|+ setNext(Handler) |
+----------------------+
|
|
|
+-----------------------+------------------------+
| |
V V
+-------------------+ +-------------------+
| ConcreteHandlerA | | ConcreteHandlerB |
+-------------------+ +-------------------+
|+ handleRequest() | |+ handleRequest() |
+-------------------+ +-------------------+
2. 责任链模式的实现
假设我们有一个支持不同等级审批的系统,处理来自员工的请假请求。不同的审批层级负责不同的天数范围,比如普通经理可以审批 1-3 天的请假,部门经理可以审批 4-7 天,HR 负责人可以审批超过 7 天的请求。
1. 定义抽象处理者接口
javaCopy codepublic abstract class LeaveHandler {
protected LeaveHandler nextHandler;
public void setNextHandler(LeaveHandler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handleRequest(int leaveDays);
}
2. 创建具体处理者
经理审批(处理 1-3 天的请假)
javaCopy codepublic class ManagerHandler extends LeaveHandler {
@Override
public void handleRequest(int leaveDays) {
if (leaveDays <= 3) {
System.out.println("经理批准了 " + leaveDays + " 天的请假");
} else if (nextHandler != null) {
nextHandler.handleRequest(leaveDays);
}
}
}
部门经理审批(处理 4-7 天的请假)
javaCopy codepublic class DepartmentManagerHandler extends LeaveHandler {
@Override
public void handleRequest(int leaveDays) {
if (leaveDays <= 7) {
System.out.println("部门经理批准了 " + leaveDays + " 天的请假");
} else if (nextHandler != null) {
nextHandler.handleRequest(leaveDays);
}
}
}
HR 负责人审批(处理超过 7 天的请假)
javaCopy codepublic class HRHandler extends LeaveHandler {
@Override
public void handleRequest(int leaveDays) {
if (leaveDays > 7) {
System.out.println("HR 批准了 " + leaveDays + " 天的请假");
} else if (nextHandler != null) {
nextHandler.handleRequest(leaveDays);
}
}
}
3. 客户端设置责任链并发起请求
javaCopy codepublic class Client {
public static void main(String[] args) {
// 创建具体的处理者
LeaveHandler manager = new ManagerHandler();
LeaveHandler departmentManager = new DepartmentManagerHandler();
LeaveHandler hr = new HRHandler();
// 设置责任链
manager.setNextHandler(departmentManager);
departmentManager.setNextHandler(hr);
// 发起请求
System.out.println("请求 2 天请假:");
manager.handleRequest(2);
System.out.println("\n请求 5 天请假:");
manager.handleRequest(5);
System.out.println("\n请求 10 天请假:");
manager.handleRequest(10);
}
}
输出结果:
plaintextCopy code请求 2 天请假:
经理批准了 2 天的请假
请求 5 天请假:
部门经理批准了 5 天的请假
请求 10 天请假:
HR 批准了 10 天的请假
3. 责任链模式的优缺点
优点
- 降低耦合度:请求发送者和处理者解耦,发送者无需关心具体哪个处理者来处理请求。
- 灵活性高:责任链的节点可以灵活组合、扩展和重用,增加或修改处理者不会影响其他处理者。
- 链式处理:请求可以按顺序被多个处理者处理,且可以动态改变链条的结构,满足不同业务场景的需求。
缺点
- 请求可能没有被处理:如果没有适合的处理者,可能会导致请求未被处理的情况,除非在链尾加一个默认处理者。
- 性能问题:如果链条过长,可能导致请求处理速度变慢。
- 调试困难:由于请求沿链条传播,可能难以调试和定位请求在哪个节点上被处理。
4. 责任链模式的应用场景
责任链模式适用于以下场景:
- 多个对象处理同一请求,且处理顺序需要灵活调整:如审批流程、权限验证、日志处理等。
- 动态指定处理者:请求的处理者在运行时动态确定,比如动态配置业务处理流程。
- 请求处理条件复杂:当有多个条件判断去决定请求的处理流程时,责任链模式可以减少代码中的条件判断,使代码更清晰。
5. 责任链模式的扩展与优化
1. 默认处理者
在链的末尾增加一个默认处理者,以确保请求总是会被处理。例如,设置一个“无权限”的处理者,在所有具体处理者都无法处理时执行默认行为,避免请求丢失。
2. 灵活配置链条
使用配置文件或数据库来配置责任链的顺序,以便根据不同需求动态改变处理者的顺序。这种方式通常与工厂模式结合使用。
3. 变种:双向链表
标准的责任链是单向链表结构。如果需要实现请求在失败时回退到前一个处理者,可以使用双向链表结构,让每个处理者既有前继节点又有后继节点,适应更复杂的业务场景。
6. 总结
- 责任链模式 是一种将请求处理从客户端解耦的模式,允许多个处理者对请求进行按顺序处理。
- 核心思想:请求从一个处理者传递到下一个处理者,直到被处理或到达链尾。
- 优点:低耦合、灵活配置处理者,减少条件判断。
- 应用场景:适合审批流程、日志处理、权限校验等需要灵活组合处理步骤的场景。