责任链
更新: 6/22/2025 字数: 0 字 时长: 0 分钟
定义
责任链模式 (Chain of Responsibility Pattern) 使多个对象都有机会处理请求,从而避免请求发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
角色
- 抽象处理器 (Handler):定义处理请求的接口
- 具体处理器 (Concrete Handler):处理请求的具体实现类
- 客户端 (Client):创建处理链并提交请求
实现
基础责任链
java
// 抽象处理器
public abstract class Handler {
protected Handler nextHandler;
public void setNext(Handler handler) {
this.nextHandler = handler;
}
public abstract void handleRequest(int request);
}
// 具体处理器 A
public class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(int request) {
if (request <= 10) {
System.out.println("HandlerA 处理请求:" + request);
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
// 具体处理器 B
public class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(int request) {
if (request > 10 && request <= 20) {
System.out.println("HandlerB 处理请求:" + request);
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
// 具体处理器 C
public class ConcreteHandlerC extends Handler {
@Override
public void handleRequest(int request) {
if (request > 20) {
System.out.println("HandlerC 处理请求:" + request);
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
// 客户端使用
public class Client {
public static void main(String[] args) {
// 创建处理器
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
Handler handlerC = new ConcreteHandlerC();
// 构建责任链
handlerA.setNext(handlerB);
handlerB.setNext(handlerC);
// 提交请求
int[] requests = {5, 15, 25, 8, 30};
for (int request : requests) {
handlerA.handleRequest(request);
}
}
}
过滤器链实现
java
// 请求对象
public class Request {
private String content;
public Request(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
// 响应对象
public class Response {
private String content;
public void setContent(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
// 过滤器接口
public interface Filter {
void doFilter(Request request, Response response, FilterChain chain);
}
// 过滤器链
public class FilterChain {
private List<Filter> filters = new ArrayList<>();
private int index = 0;
public FilterChain addFilter(Filter filter) {
filters.add(filter);
return this;
}
public void doFilter(Request request, Response response) {
if (index < filters.size()) {
Filter filter = filters.get(index++);
filter.doFilter(request, response, this);
}
}
}
// HTML 转义过滤器
public class HtmlFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
// 处理请求
String processed = request.getContent()
.replace("<", "<")
.replace(">", ">");
request = new Request(processed);
// 继续链
chain.doFilter(request, response);
// 处理响应
response.setContent(response.getContent() + "--HtmlFilter");
}
}
// 敏感词过滤器
public class SensitiveFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
// 处理请求
String processed = request.getContent()
.replace("敏感词", "***");
request = new Request(processed);
// 继续链
chain.doFilter(request, response);
// 处理响应
response.setContent(response.getContent() + "--SensitiveFilter");
}
}
// 使用示例
public class FilterDemo {
public static void main(String[] args) {
// 创建过滤器链
FilterChain chain = new FilterChain();
chain.addFilter(new HtmlFilter())
.addFilter(new SensitiveFilter());
// 创建请求响应对象
Request request = new Request("<script>敏感词测试</script>");
Response response = new Response();
// 执行过滤链
chain.doFilter(request, response);
System.out.println("处理后的请求:" + request.getContent());
System.out.println("处理后的响应:" + response.getContent());
}
}
优缺点
优点:
- 降低耦合度:请求发送者无需知道具体处理者
- 增强系统灵活性:可动态调整责任链
- 符合开闭原则:可新增处理者而不修改现有代码
- 责任分配明确:每个处理者专注特定职责
缺点:
- 请求可能未被处理(链尾未处理)
- 调试困难:请求传递路径复杂
- 性能影响:长链导致处理延迟
- 循环引用风险:处理者相互引用导致死循环
应用场景
- 多级审批系统(请假、报销)
- 异常处理机制(Java 异常处理)
- 过滤器链(Servlet Filter)
- 日志处理系统(不同级别日志处理器)
- 事件传递机制(GUI 事件处理)
- 权限验证系统(多级权限检查)
与其他模式的关系
- 与命令模式:责任链传递请求,命令封装请求
- 与组合模式:可组合处理器形成树形结构
- 与装饰器模式:都使用链式结构,但目的不同
- 与状态模式:状态转移 vs 请求传递
- 与中介者模式:中介集中控制,责任链分散处理
JDK 中的责任链模式
- Java 异常处理机制(try-catch-finally)
- Servlet 过滤器(FilterChain)
- AOP 拦截器链(Spring Interceptor)
- Java 日志框架(Logger handlers)
- Java NIO 事件处理(ChannelPipeline)
- Spring Security 过滤器链
注意事项
- 明确链的终止条件(避免无限传递)
- 控制链的长度(性能考虑)
- 考虑请求优先级(前置处理 vs 后置处理)
- 处理未处理请求(默认处理器)
- 避免循环引用(链成环)
- 线程安全问题(共享处理器状态)
- 合理设置处理者粒度(避免过大或过小)