责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,核心思想是将多个处理请求的对象连成一条链,请求沿链传递直到被处理。它像现实中的“多级审批流程”——请假或报销时,申请会逐级提交给不同权限的领导,直到有人能处理为止。
一、通俗理解
假设你开发一个多级审批系统:
- 传统方式:用大量
if-else
判断不同金额的报销单由谁审批,代码臃肿且难以扩展。 - 责任链模式:
- 抽象审批人:定义统一的处理接口,并持有下一级审批人的引用。
- 具体审批人(如组长、经理、CEO):各自处理权限内的请求,超出权限则转交下一级。
最终只需将审批人连成链,客户端提交请求到链头,无需关心具体处理细节。
二、模式结构
- 抽象处理者(Handler):定义处理请求的接口,包含设置下一处理者的方法(如
setNext()
)。 - 具体处理者(ConcreteHandler):实现处理逻辑,若无法处理则转交下一级。
- 客户端(Client):创建处理链,发起请求。
三、适用场景
- 多级审批流程:如请假、报销、工单处理。
- 动态扩展处理逻辑:如日志过滤器、权限验证链。
- 请求发送者与接收者解耦:如 GUI 事件传递、网络请求拦截器。
四、代码实现
1. C++ 示例(报销审批链)
#include <iostream>
// 抽象处理者
class Approver {
protected:
Approver* next = nullptr;
public:
void setNext(Approver* nextApprover) {
next = nextApprover;
}
virtual void handle(int amount) = 0;
};
// 具体处理者:组长
class GroupLeader : public Approver {
public:
void handle(int amount) override {
if (amount <= 1000) {
std::cout << "组长审批通过(金额:" << amount << "元)" << std::endl;
} else if (next) {
next->handle(amount);
} else {
std::cout << "无人能处理此金额!" << std::endl;
}
}
};
// 具体处理者:经理
class Manager : public Approver {
public:
void handle(int amount) override {
if (amount <= 5000) {
std::cout << "经理审批通过(金额:" << amount << "元)" << std::endl;
} else if (next) {
next->handle(amount);
}
}
};
int main() {
GroupLeader leader;
Manager manager;
leader.setNext(&manager);
leader.handle(800); // 组长处理
leader.handle(3000); // 经理处理
leader.handle(10000); // 无处理
return 0;
}
输出:
组长审批通过(金额:800元)
经理审批通过(金额:3000元)
无人能处理此金额!
解析:
- 组长处理 ≤1000 元的请求,否则转交经理。
- 经理处理 ≤5000 元的请求,更高金额无后续处理者。
2. Python 示例(日志过滤器链)
from abc import ABC, abstractmethod
class LogHandler(ABC):
def __init__(self):
self.next = None
def set_next(self, next_handler):
self.next = next_handler
@abstractmethod
def handle(self, log_level, message):
pass
class DebugHandler(LogHandler):
def handle(self, log_level, message):
if log_level == "DEBUG":
print(f"[DEBUG] {message}")
elif self.next:
self.next.handle(log_level, message)
class ErrorHandler(LogHandler):
def handle(self, log_level, message):
if log_level == "ERROR":
print(f"[ERROR] {message}")
elif self.next:
self.next.handle(log_level, message)
# 客户端
debug = DebugHandler()
error = ErrorHandler()
debug.set_next(error)
debug.handle("DEBUG", "调试信息") # [DEBUG] 调试信息
debug.handle("ERROR", "系统崩溃") # [ERROR] 系统崩溃
debug.handle("INFO", "普通日志") # 无输出
解析:
DebugHandler
处理DEBUG
日志,其他级别转交下一处理者。- 链式调用避免硬编码日志级别判断。
3. Java 示例(请假审批系统)
// 抽象处理者
abstract class Approver {
protected Approver next;
public void setNext(Approver next) {
this.next = next;
}
public abstract void handle(int days);
}
// 具体处理者:组长
class GroupLeader extends Approver {
@Override
public void handle(int days) {
if (days <= 3) {
System.out.println("组长批准请假 " + days + "天");
} else if (next != null) {
next.handle(days);
}
}
}
// 具体处理者:经理
class Manager extends Approver {
@Override
public void handle(int days) {
if (days <= 7) {
System.out.println("经理批准请假 " + days + "天");
} else if (next != null) {
next.handle(days);
}
}
}
public class Client {
public static void main(String[] args) {
GroupLeader leader = new GroupLeader();
Manager manager = new Manager();
leader.setNext(manager);
leader.handle(2); // 组长处理
leader.handle(5); // 经理处理
leader.handle(10); // 无处理
}
}
输出:
组长批准请假 2天
经理批准请假 5天
解析:
- 组长处理 ≤3 天的请假,其余转交经理。
- 责任链动态组合,新增审批人只需扩展链。
五、优缺点分析
优点 | 缺点 |
---|---|
1. 解耦请求与处理逻辑:客户端无需知道具体处理者 | 1. 性能问题:长链可能导致请求传递慢 |
2. 灵活扩展:动态增减处理节点,符合开闭原则 | 2. 调试困难:请求可能未被处理或循环传递 |
3. 单一职责:每个处理者专注自身逻辑 | 3. 链配置错误风险:需确保链正确连接 |
六、总结
责任链模式通过链式传递请求,实现了处理逻辑的动态组合与解耦。适用于多级审批、日志过滤等场景,但需注意链长控制和错误处理。其核心价值在于:
- 灵活扩展:新增处理者无需修改原有代码。
- 职责分离:每个处理者只关注自身任务。
- 实际应用:如 Spring MVC 的拦截器链、Netty 的 ChannelPipeline。