责任链模式详解
一、责任链模式概述
责任链模式(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框架的过滤器链
- 审批工作流系统
- 异常处理系统
- 事件处理管道
- 中间件设计
正确使用责任链模式可以提高系统的灵活性和可扩展性,但需要注意控制处理链的复杂度,避免性能问题。