责任链模式 (Chain of Responsibility)
什么是责任链模式?
责任链模式是一种行为型设计模式,它允许你将请求沿着处理者链进行传递。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下一个处理者。
核心思想
- 解耦发送者和接收者:请求的发送者不需要知道哪个对象会处理请求。
- 动态组合处理者:可以在运行时动态地添加或修改处理链。
- 单一职责:每个处理者只负责自己能处理的请求。
实现示例:日志系统
抽象处理器
java
import lombok.Setter;
/**
* 抽象日志处理器
* @author yjhu
*/
public abstract class AbstractLogger {
public static final int INFO = 1;
public static final int DEBUG = 2;
public static final int ERROR = 3;
protected int level;
// 责任链中的下一个元素
@Setter
protected AbstractLogger nextLogger;
public void logMessage(int level, String message) {
if (this.level <= level) {
write(message);
}
// 传递给下一个处理器
if (nextLogger != null) {
nextLogger.logMessage(level, message);
}
}
protected abstract void write(String message);
}具体处理器
java
/**
* 控制台日志处理器
* @author yjhu
*/
public class ConsoleLogger extends AbstractLogger {
public ConsoleLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("[Console] " + message);
}
}
/**
* 文件日志处理器
* @author yjhu
*/
public class FileLogger extends AbstractLogger {
public FileLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("[File] " + message);
}
}
/**
* 错误日志处理器(发送邮件通知)
* @author yjhu
*/
public class ErrorLogger extends AbstractLogger {
public ErrorLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("[Error - Email Alert] " + message);
}
}构建责任链并使用
java
/**
* 责任链构建器
* @author yjhu
*/
public class LoggerChainBuilder {
public static AbstractLogger buildChain() {
// 创建处理器
AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);
// 构建链:Console -> File -> Error
consoleLogger.setNextLogger(fileLogger);
fileLogger.setNextLogger(errorLogger);
return consoleLogger;
}
}
// 使用示例
public class Demo {
public static void main(String[] args) {
AbstractLogger loggerChain = LoggerChainBuilder.buildChain();
System.out.println("=== INFO 级别日志 ===");
loggerChain.logMessage(AbstractLogger.INFO, "这是一条普通信息");
System.out.println("\n=== DEBUG 级别日志 ===");
loggerChain.logMessage(AbstractLogger.DEBUG, "这是一条调试信息");
System.out.println("\n=== ERROR 级别日志 ===");
loggerChain.logMessage(AbstractLogger.ERROR, "这是一条错误信息!");
}
}输出结果
=== INFO 级别日志 ===
[Console] 这是一条普通信息
=== DEBUG 级别日志 ===
[Console] 这是一条调试信息
[File] 这是一条调试信息
=== ERROR 级别日志 ===
[Console] 这是一条错误信息!
[File] 这是一条错误信息!
[Error - Email Alert] 这是一条错误信息!适用场景
- 审批流程:请假、报销等需要多级审批的场景。
- 过滤器链:Servlet Filter、Spring Interceptor。
- 事件处理:GUI 中的事件冒泡机制。
- 日志记录:不同级别的日志输出到不同目标。
责任链模式的两种变体
| 变体 | 描述 | 示例 |
|---|---|---|
| 纯责任链 | 请求只能被一个处理者处理,处理后不再传递 | 审批流程 |
| 不纯责任链 | 请求可以被多个处理者处理后继续传递 | 日志系统、过滤器链 |
实际应用
- Servlet Filter:多个 Filter 组成过滤器链。
- Spring Security:
FilterChainProxy管理安全过滤器链。 - Netty:
ChannelPipeline中的ChannelHandler链。 - OkHttp:拦截器链(Interceptor Chain)。
优缺点
优点
- ✅ 降低耦合度,请求发送者和接收者解耦。
- ✅ 增强灵活性,可动态增加或修改处理者。
- ✅ 符合单一职责原则,每个处理者只关注自己的逻辑。
缺点
- ❌ 不能保证请求一定会被处理。
- ❌ 调试困难,需要跟踪整个链路。
- ❌ 链过长可能影响性能。
