责任链模式详解
一、责任链模式概述
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许你将请求沿着处理链传递,直到有一个处理者能够处理它为止。这种模式解耦了请求的发送者和接收者,使多个对象都有机会处理请求。
核心特点
- 解耦请求与处理:发送者不需要知道具体由哪个处理者处理请求
- 动态组合:可以动态地改变处理链
- 灵活性:可以灵活地新增或修改处理流程
- 多重处理:一个请求可以被多个处理者处理
二、责任链模式的结构
主要角色
- Handler:抽象处理者,定义处理请求的接口
- ConcreteHandler:具体处理者,实现处理逻辑
- Client:客户端,创建处理链并提交请求
三、责任链模式的实现
1. 基本实现
// 抽象处理者
public abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(Request request);
}
// 具体处理者A
public class ConcreteHandlerA extends Handler {
public void handleRequest(Request request) {
if (request.getType().equals("TypeA")) {
System.out.println("HandlerA处理请求: " + request.getContent());
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理者B
public class ConcreteHandlerB extends Handler {
public void handleRequest(Request request) {
if (request.getType().equals("TypeB")) {
System.out.println("HandlerB处理请求: " + request.getContent());
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 请求对象
public class Request {
private String type;
private String content;
public Request(String type, String content) {
this.type = type;
this.content = content;
}
// getter方法
public String getType() { return type; }
public String getContent() { return content; }
}
// 使用示例
Handler h1 = new ConcreteHandlerA();
Handler h2 = new ConcreteHandlerB();
h1.setSuccessor(h2);
Request request = new Request("TypeB", "测试请求");
h1.handleRequest(request);
2. 更灵活的实现(带中断)
public interface Handler {
boolean handle(Request request);
}
public class AuthHandler implements Handler {
public boolean handle(Request request) {
if (!request.isAuthenticated()) {
System.out.println("认证失败");
return false;
}
System.out.println("认证通过");
return true;
}
}
public class LoggingHandler implements Handler {
public boolean handle(Request request) {
System.out.println("记录请求日志: " + request);
return true;
}
}
public class ProcessingHandler implements Handler {
public boolean handle(Request request) {
System.out.println("处理业务请求: " + request);
return true;
}
}
public class HandlerChain {
private List<Handler> handlers = new ArrayList<>();
public HandlerChain addHandler(Handler handler) {
handlers.add(handler);
return this;
}
public boolean process(Request request) {
for (Handler handler : handlers) {
if (!handler.handle(request)) {
return false;
}
}
return true;
}
}
// 使用示例
HandlerChain chain = new HandlerChain()
.addHandler(new AuthHandler())
.addHandler(new LoggingHandler())
.addHandler(new ProcessingHandler());
Request request = new Request("test");
chain.process(request);
四、责任链模式的应用场景
1. Web请求过滤器
public interface Filter {
void doFilter(HttpRequest request, HttpResponse response, FilterChain chain);
}
public class AuthenticationFilter implements Filter {
public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {
if (!request.isAuthenticated()) {
response.setStatus(401);
return;
}
System.out.println("认证通过");
chain.doFilter(request, response);
}
}
public class LoggingFilter implements Filter {
public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {
System.out.println("请求日志: " + request.getPath());
chain.doFilter(request, response);
}
}
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(HttpRequest request, HttpResponse response) {
if (index < filters.size()) {
Filter filter = filters.get(index++);
filter.doFilter(request, response, this);
}
}
}
2. 审批流程系统
public abstract class Approver {
protected Approver successor;
protected String name;
public Approver(String name) {
this.name = name;
}
public void setSuccessor(Approver successor) {
this.successor = successor;
}
public abstract void processRequest(PurchaseRequest request);
}
public class DepartmentHead extends Approver {
public DepartmentHead(String name) {
super(name);
}
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 5000) {
System.out.println("部门主管" + name + "审批采购单: " + request);
} else if (successor != null) {
successor.processRequest(request);
}
}
}
public class VicePresident extends Approver {
public VicePresident(String name) {
super(name);
}
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 10000) {
System.out.println("副总裁" + name + "审批采购单: " + request);
} else if (successor != null) {
successor.processRequest(request);
}
}
}
// 使用示例
Approver zhangsan = new DepartmentHead("张三");
Approver lisi = new VicePresident("李四");
zhangsan.setSuccessor(lisi);
PurchaseRequest request = new PurchaseRequest(8000, "购买设备");
zhangsan.processRequest(request);
3. 异常处理系统
public interface ExceptionHandler {
void handle(Exception e, ExceptionHandlerChain chain);
}
public class NullPointerHandler implements ExceptionHandler {
public void handle(Exception e, ExceptionHandlerChain chain) {
if (e instanceof NullPointerException) {
System.out.println("处理空指针异常");
} else {
chain.handle(e);
}
}
}
public class IOExceptionHandler implements ExceptionHandler {
public void handle(Exception e, ExceptionHandlerChain chain) {
if (e instanceof IOException) {
System.out.println("处理IO异常");
} else {
chain.handle(e);
}
}
}
public class DefaultExceptionHandler implements ExceptionHandler {
public void handle(Exception e, ExceptionHandlerChain chain) {
System.out.println("默认异常处理");
}
}
public class ExceptionHandlerChain {
private List<ExceptionHandler> handlers = new ArrayList<>();
private int index = 0;
public ExceptionHandlerChain addHandler(ExceptionHandler handler) {
handlers.add(handler);
return this;
}
public void handle(Exception e) {
if (index < handlers.size()) {
ExceptionHandler handler = handlers.get(index++);
handler.handle(e, this);
}
}
}
五、责任链模式的变体
1. 功能链模式
public interface Function<T, R> {
R apply(T t, Function<T, R> next);
}
public class FunctionChain<T, R> {
private List<Function<T, R>> functions = new ArrayList<>();
public FunctionChain<T, R> addFunction(Function<T, R> function) {
functions.add(function);
return this;
}
public R execute(T input) {
if (functions.isEmpty()) return null;
Function<T, R> first = functions.get(0);
return first.apply(input, (t, n) -> {
int nextIndex = functions.indexOf(n) + 1;
if (nextIndex < functions.size()) {
return functions.get(nextIndex).apply(t, functions.get(nextIndex));
}
return null;
});
}
}
2. 中断式责任链
public abstract class InterruptibleHandler {
private InterruptibleHandler next;
public void setNext(InterruptibleHandler next) {
this.next = next;
}
public final void handle(Request request) {
if (!doHandle(request) && next != null) {
next.handle(request);
}
}
protected abstract boolean doHandle(Request request);
}
六、责任链模式的优缺点
优点
- 降低耦合度:请求发送者与接收者解耦
- 增强灵活性:可以动态调整处理链
- 简化对象:每个处理者只需关注自己的责任范围
- 易于扩展:新增处理者不影响现有代码
缺点
- 请求可能未被处理:如果没有处理者能处理请求
- 性能影响:较长的处理链可能影响性能
- 调试困难:请求的传递过程可能不易追踪
七、最佳实践
- 明确处理范围:每个处理者应明确自己的处理范围
- 控制链的长度:避免过长的处理链影响性能
- 提供默认处理:确保请求最终能被处理
- 日志记录:记录请求在链中的传递过程
- 考虑中断机制:允许在处理过程中中断传递
八、总结
责任链模式是处理复杂流程的有效方案,特别适用于:
- 有多个对象可以处理同一请求
- 需要动态指定处理流程
- 需要解耦请求发送者和接收者
- 处理流程可能变化的情况
在实际开发中,责任链模式常见于:
- Web框架的过滤器链
- 审批工作流系统
- 异常处理系统
- 事件处理管道
- 中间件设计
正确使用责任链模式可以提高系统的灵活性和可扩展性,但需要注意控制处理链的复杂度,避免性能问题。