设计模式手册012:责任链模式 - 请求处理的流水线艺术
本文是「设计模式手册」系列第012篇,我们将深入探讨责任链模式,这种模式让多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
1. 场景:我们为何需要责任链模式?
在软件开发中,我们经常遇到需要多个对象按顺序处理请求的场景:
- 审批流程:请假申请需要经过组长、经理、总监层层审批
- 过滤器链:Web请求需要经过认证、授权、日志等过滤器
- 异常处理:异常需要被多个处理器按顺序尝试处理
- 消息处理:消息需要经过解析、验证、转换等多个处理器
传统做法的困境:
java
// 传统的硬编码处理流程
public class LeaveApplication {
private String employeeName;
private int leaveDays;
private String reason;
// 构造器、getter、setter...
}
public class LeaveApprovalService {
public boolean approve(LeaveApplication application) {
// 硬编码的处理顺序
System.out.println("提交给组长审批...");
if (!teamLeaderApprove(application)) {
return false;
}
System.out.println("提交给经理审批...");
if (!managerApprove(application)) {
return false;
}
System.out.println("提交给总监审批...");
if (!directorApprove(application)) {
return false;
}
return true;
}
private boolean teamLeaderApprove(LeaveApplication application) {
// 组长审批逻辑:3天以内直接批准
if (application.getLeaveDays() <= 3) {
System.out.println("组长批准了 " + application.getEmployeeName() + " 的 " +
application.getLeaveDays() + " 天请假");
return true;
}
System.out.println("组长无法批准 " + application.getLeaveDays() + " 天请假,转交经理");
return true; // 继续传递
}
private boolean managerApprove(LeaveApplication application) {
// 经理审批逻辑:7天以内批准
if (application.getLeaveDays() <= 7) {
System.out.println("经理批准了 " + application.getEmployeeName() + " 的 " +
application.getLeaveDays() + " 天请假");
return true;
}
System.out.println("经理无法批准 " + application.getLeaveDays() + " 天请假,转交总监");
return true; // 继续传递
}
private boolean directorApprove(LeaveApplication application) {
// 总监审批逻辑:15天以内批准
if (application.getLeaveDays() <= 15) {
System.out.println("总监批准了 " + application.getEmployeeName() + " 的 " +
application.getLeaveDays() + " 天请假");
return true;
}
System.out.println("总监驳回了 " + application.getLeaveDays() + " 天请假,时间过长");
return false;
}
}
// 使用示例
public class TraditionalApproval {
public static void main(String[] args) {
LeaveApprovalService service = new LeaveApprovalService();
LeaveApplication app1 = new LeaveApplication("张三", 2, "个人事务");
boolean result1 = service.approve(app1);
System.out.println("结果: " + (result1 ? "批准" : "驳回"));
System.out.println("\n=== 分割线 ===\n");
LeaveApplication app2 = new LeaveApplication("李四", 10, "旅游");
boolean result2 = service.approve(app2);
System.out.println("结果: " + (result2 ? "批准" : "驳回"));
}
}
这种实现的痛点:
- 硬编码顺序:处理顺序在代码中固定,难以修改
- 违反开闭原则:新增处理者需要修改现有代码
- 职责不单一:审批服务包含了所有审批逻辑
- 难以测试:各个审批逻辑耦合在一起
2. 责任链模式:定义与本质
2.1 模式定义
责任链模式(Chain of Responsibility Pattern):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
2.2 核心角色
java
// 处理者接口
public interface LeaveApprover {
void setNextApprover(LeaveApprover nextApprover);
boolean approve(LeaveApplication application);
boolean canApprove(LeaveApplication application);
}
// 抽象处理者
public abstract class AbstractLeaveApprover implements LeaveApprover {
protected LeaveApprover nextApprover;
protected String approverName;
protected String approverRole;
public AbstractLeaveApprover(String name, String role) {
this.approverName = name;
this.approverRole = role;
}
@Override
public void setNextApprover(LeaveApprover nextApprover) {
this.nextApprover = nextApprover;
}
@Override
public boolean approve(LeaveApplication application) {
// 如果当前处理者能够处理,则处理并返回
if (canApprove(application)) {
return doApprove(application);
}
// 否则传递给下一个处理者
if (nextApprover != null) {
System.out.println(approverRole + " " + approverName +
" 无法处理,转交给 " + getNextApproverInfo());
return nextApprover.approve(application);
}
// 没有下一个处理者,请求无法处理
System.out.println("请求无法处理,没有合适的审批人");
return false;
}
protected abstract boolean doApprove(LeaveApplication application);
protected abstract boolean canApprove(LeaveApplication application);
private String getNextApproverInfo() {
if (nextApprover instanceof AbstractLeaveApprover) {
AbstractLeaveApprover next = (AbstractLeaveApprover) nextApprover;
return next.approverRole + " " + next.approverName;
}
return "下一审批人";
}
}
// 具体处理者 - 组长
public class TeamLeader extends AbstractLeaveApprover {
private static final int MAX_DAYS = 3;
public TeamLeader(String name) {
super(name, "组长");
}
@Override
protected boolean doApprove(LeaveApplication application) {
System.out.println(approverRole + " " + approverName +
" 批准了 " + application.getEmployeeName() +
" 的 " + application.getLeaveDays() + " 天请假");
return true;
}
@Override
protected boolean canApprove(LeaveApplication application) {
return application.getLeaveDays() <= MAX_DAYS;
}
}
// 具体处理者 - 经理
public class Manager extends AbstractLeaveApprover {
private static final int MAX_DAYS = 7;
public Manager(String name) {
super(name, "经理");
}
@Override
protected boolean doApprove(LeaveApplication application) {
System.out.println(approverRole + " " + approverName +
" 批准了 " + application.getEmployeeName() +
" 的 " + application.getLeaveDays() + " 天请假");
return true;
}
@Override
protected boolean canApprove(LeaveApplication application) {
return application.getLeaveDays() <= MAX_DAYS;
}
}
// 具体处理者 - 总监
public class Director extends AbstractLeaveApprover {
private static final int MAX_DAYS = 15;
public Director(String name) {
super(name, "总监");
}
@Override
protected boolean doApprove(LeaveApplication application) {
System.out.println(approverRole + " " + approverName +
" 批准了 " + application.getEmployeeName() +
" 的 " + application.getLeaveDays() + " 天请假");
return true;
}
@Override
protected boolean canApprove(LeaveApplication application) {
return application.getLeaveDays() <= MAX_DAYS;
}
}
// 请假申请类
@Data
public class LeaveApplication {
private String employeeName;
private int leaveDays;
private String reason;
public LeaveApplication(String employeeName, int leaveDays, String reason) {
this.employeeName = employeeName;
this.leaveDays = leaveDays;
this.reason = reason;
}
}
3. 深入理解:责任链模式的多维视角
3.1 第一重:纯责任链 vs 不纯责任链
纯责任链模式
java
// 纯责任链:每个处理者要么完全处理请求,要么完全不处理
public abstract class PureHandler {
protected PureHandler next;
public void setNext(PureHandler next) {
this.next = next;
}
public final void handle(Request request) {
if (canHandle(request)) {
doHandle(request);
} else if (next != null) {
next.handle(request);
} else {
// 无法处理,抛出异常或记录日志
throw new UnsupportedOperationException("无法处理请求: " + request);
}
}
protected abstract boolean canHandle(Request request);
protected abstract void doHandle(Request request);
}
不纯责任链模式
java
// 不纯责任链:处理者可以处理部分请求,然后继续传递
public abstract class ImpureHandler {
protected ImpureHandler next;
public void setNext(ImpureHandler next) {
this.next = next;
}
public final void handle(Request request) {
// 先进行前置处理
preHandle(request);
// 如果能够处理主要逻辑,则处理
if (canHandle(request)) {
doHandle(request);
}
// 无论是否处理,都继续传递(可以选择性地传递)
if (shouldContinue(request) && next != null) {
next.handle(request);
}
// 后置处理
postHandle(request);
}
protected abstract boolean canHandle(Request request);
protected abstract void doHandle(Request request);
protected void preHandle(Request request) {}
protected void postHandle(Request request) {}
protected boolean shouldContinue(Request request) { return true; }
}
3.2 第二重:链的构建方式
手动构建链
java
// 手动构建责任链
public class ChainBuilder {
public static LeaveApprover buildLeaveApprovalChain() {
TeamLeader teamLeader = new TeamLeader("张组长");
Manager manager = new Manager("李经理");
Director director = new Director("王总监");
teamLeader.setNextApprover(manager);
manager.setNextApprover(director);
return teamLeader; // 返回链头
}
}
使用建造者模式构建链
java
// 链建造者
public class ApprovalChainBuilder {
private LeaveApprover head;
private LeaveApprover tail;
public ApprovalChainBuilder addApprover(LeaveApprover approver) {
if (head == null) {
head = approver;
tail = approver;
} else {
tail.setNextApprover(approver);
tail = approver;
}
return this;
}
public LeaveApprover build() {
return head;
}
}
3.3 第三重:链的终止条件
java
// 可配置的终止条件
public abstract class ConfigurableHandler extends AbstractLeaveApprover {
protected boolean stopOnSuccess; // 处理成功时是否停止
protected boolean stopOnFailure; // 处理失败时是否停止
public ConfigurableHandler(String name, String role,
boolean stopOnSuccess, boolean stopOnFailure) {
super(name, role);
this.stopOnSuccess = stopOnSuccess;
this.stopOnFailure = stopOnFailure;
}
@Override
public boolean approve(LeaveApplication application) {
if (canApprove(application)) {
boolean result = doApprove(application);
if (result && stopOnSuccess) {
return true;
}
if (!result && stopOnFailure) {
return false;
}
}
if (nextApprover != null) {
return nextApprover.approve(application);
}
return false;
}
}
4. 实战案例:完整的Web请求过滤器链
java
// 过滤器接口
public interface Filter {
void doFilter(HttpRequest request, HttpResponse response, FilterChain chain);
int getOrder(); // 执行顺序
}
// 过滤器链
public class FilterChain {
private List<Filter> filters = new ArrayList<>();
private int index = 0;
public void addFilter(Filter filter) {
filters.add(filter);
// 按顺序排序
filters.sort(Comparator.comparingInt(Filter::getOrder));
}
public void doFilter(HttpRequest request, HttpResponse response) {
if (index < filters.size()) {
Filter filter = filters.get(index++);
filter.doFilter(request, response, this);
}
}
// 重置链,允许重用
public void reset() {
index = 0;
}
}
// 具体的过滤器
public class AuthenticationFilter implements Filter {
@Override
public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {
System.out.println("=== 执行身份认证过滤器 ===");
String token = request.getHeader("Authorization");
if (token == null || !isValidToken(token)) {
response.setStatusCode(401);
response.setBody("未授权访问");
return;
}
System.out.println("身份认证通过");
chain.doFilter(request, response);
}
@Override
public int getOrder() {
return 10; // 第一个执行
}
private boolean isValidToken(String token) {
// 实际的token验证逻辑
return token.startsWith("Bearer ");
}
}
public class LoggingFilter implements Filter {
@Override
public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {
System.out.println("=== 执行日志过滤器 ===");
long startTime = System.currentTimeMillis();
System.out.println("请求开始: " + request.getMethod() + " " + request.getPath());
System.out.println("请求头: " + request.getHeaders());
chain.doFilter(request, response);
long endTime = System.currentTimeMillis();
System.out.println("请求结束,耗时: " + (endTime - startTime) + "ms");
System.out.println("响应状态: " + response.getStatusCode());
}
@Override
public int getOrder() {
return 20;
}
}
public class ValidationFilter implements Filter {
@Override
public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {
System.out.println("=== 执行参数验证过滤器 ===");
if (request.getMethod().equals("POST") || request.getMethod().equals("PUT")) {
if (request.getBody() == null || request.getBody().trim().isEmpty()) {
response.setStatusCode(400);
response.setBody("请求体不能为空");
return;
}
}
System.out.println("参数验证通过");
chain.doFilter(request, response);
}
@Override
public int getOrder() {
return 30;
}
}
public class RateLimitingFilter implements Filter {
private Map<String, AtomicInteger> requestCounts = new ConcurrentHashMap<>();
private static final int MAX_REQUESTS_PER_MINUTE = 100;
@Override
public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {
System.out.println("=== 执行限流过滤器 ===");
String clientIp = request.getClientIp();
AtomicInteger count = requestCounts.computeIfAbsent(clientIp, k -> new AtomicInteger(0));
if (count.incrementAndGet() > MAX_REQUESTS_PER_MINUTE) {
response.setStatusCode(429);
response.setBody("请求过于频繁,请稍后重试");
return;
}
System.out.println("限流检查通过,客户端 " + clientIp + " 当前请求数: " + count.get());
chain.doFilter(request, response);
}
@Override
public int getOrder() {
return 40;
}
// 定时重置计数器(实际项目中应该使用更复杂的限流算法)
public void resetCounters() {
requestCounts.clear();
}
}
// 业务处理器
public class BusinessHandler {
public void handleRequest(HttpRequest request, HttpResponse response) {
System.out.println("=== 执行业务逻辑 ===");
// 模拟业务处理
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
response.setStatusCode(200);
response.setBody("{\"message\": \"请求处理成功\", \"data\": {}}");
System.out.println("业务处理完成");
}
}
// HTTP请求和响应类
@Data
public class HttpRequest {
private String method;
private String path;
private Map<String, String> headers = new HashMap<>();
private String body;
private String clientIp;
public String getHeader(String name) {
return headers.get(name);
}
}
@Data
public class HttpResponse {
private int statusCode = 200;
private Map<String, String> headers = new HashMap<>();
private String body = "";
}
// Web服务器模拟
public class WebServer {
private FilterChain filterChain;
private BusinessHandler businessHandler;
public WebServer() {
this.filterChain = new FilterChain();
this.businessHandler = new BusinessHandler();
// 构建过滤器链
initializeFilters();
}
private void initializeFilters() {
filterChain.addFilter(new AuthenticationFilter());
filterChain.addFilter(new LoggingFilter());
filterChain.addFilter(new ValidationFilter());
filterChain.addFilter(new RateLimitingFilter());
}
public void handleRequest(HttpRequest request, HttpResponse response) {
System.out.println("=== 开始处理请求 ===");
try {
// 执行过滤器链
filterChain.doFilter(request, response);
// 如果过滤器链没有中断,执行业务逻辑
if (response.getStatusCode() == 200) {
businessHandler.handleRequest(request, response);
}
} catch (Exception e) {
response.setStatusCode(500);
response.setBody("服务器内部错误: " + e.getMessage());
} finally {
filterChain.reset(); // 重置链以便下次使用
}
System.out.println("=== 请求处理结束 ===\n");
}
}
// 使用示例
public class WebServerDemo {
public static void main(String[] args) {
WebServer server = new WebServer();
// 测试用例1:正常请求
System.out.println("测试用例1:正常请求");
HttpRequest request1 = createValidRequest();
HttpResponse response1 = new HttpResponse();
server.handleRequest(request1, response1);
System.out.println("响应: " + response1.getStatusCode() + " - " + response1.getBody());
// 测试用例2:未授权请求
System.out.println("测试用例2:未授权请求");
HttpRequest request2 = createUnauthorizedRequest();
HttpResponse response2 = new HttpResponse();
server.handleRequest(request2, response2);
System.out.println("响应: " + response2.getStatusCode() + " - " + response2.getBody());
// 测试用例3:无效参数请求
System.out.println("测试用例3:无效参数请求");
HttpRequest request3 = createInvalidRequest();
HttpResponse response3 = new HttpResponse();
server.handleRequest(request3, response3);
System.out.println("响应: " + response3.getStatusCode() + " - " + response3.getBody());
}
private static HttpRequest createValidRequest() {
HttpRequest request = new HttpRequest();
request.setMethod("POST");
request.setPath("/api/users");
request.getHeaders().put("Authorization", "Bearer token123");
request.setBody("{\"name\": \"张三\", \"email\": \"zhangsan@example.com\"}");
request.setClientIp("192.168.1.100");
return request;
}
private static HttpRequest createUnauthorizedRequest() {
HttpRequest request = new HttpRequest();
request.setMethod("GET");
request.setPath("/api/users");
request.setClientIp("192.168.1.101");
return request;
}
private static HttpRequest createInvalidRequest() {
HttpRequest request = new HttpRequest();
request.setMethod("POST");
request.setPath("/api/users");
request.getHeaders().put("Authorization", "Bearer token123");
request.setBody(""); // 空请求体
request.setClientIp("192.168.1.102");
return request;
}
}
5. Spring框架中的责任链模式
5.1 Spring Security的过滤器链
java
// 模拟Spring Security的过滤器链
@Component
public class SecurityFilterChain {
private List<SecurityFilter> filters = new ArrayList<>();
@PostConstruct
public void initialize() {
// 按安全重要性顺序添加过滤器
filters.add(new CsrfFilter());
filters.add(new LogoutFilter());
filters.add(new UsernamePasswordAuthenticationFilter());
filters.add(new BasicAuthenticationFilter());
filters.add(new AuthorizationFilter());
}
public void doFilter(HttpServletRequest request, HttpServletResponse response) {
SecurityContext context = SecurityContextHolder.getContext();
for (SecurityFilter filter : filters) {
if (!filter.doFilter(request, response, context)) {
// 如果过滤器返回false,中断链
return;
}
}
// 所有安全检查通过,继续处理请求
// chain.doFilter(request, response);
}
}
// 安全过滤器接口
public interface SecurityFilter {
boolean doFilter(HttpServletRequest request, HttpServletResponse response, SecurityContext context);
}
// 具体的安全过滤器
@Component
public class CsrfFilter implements SecurityFilter {
@Override
public boolean doFilter(HttpServletRequest request, HttpServletResponse response, SecurityContext context) {
if (!request.getMethod().equals("GET") && !request.getMethod().equals("HEAD")) {
String csrfToken = request.getHeader("X-CSRF-TOKEN");
String sessionToken = (String) request.getSession().getAttribute("CSRF_TOKEN");
if (csrfToken == null || !csrfToken.equals(sessionToken)) {
response.setStatus(403);
return false;
}
}
return true;
}
}
@Component
public class UsernamePasswordAuthenticationFilter implements SecurityFilter {
@Override
public boolean doFilter(HttpServletRequest request, HttpServletResponse response, SecurityContext context) {
if (request.getRequestURI().equals("/login") && request.getMethod().equals("POST")) {
String username = request.getParameter("username");
String password = request.getParameter("password");
Authentication authentication = authenticate(username, password);
if (authentication != null) {
context.setAuthentication(authentication);
} else {
response.setStatus(401);
return false;
}
}
return true;
}
private Authentication authenticate(String username, String password) {
// 实际的认证逻辑
if ("admin".equals(username) && "password".equals(password)) {
return new UsernamePasswordAuthenticationToken(username, password, new ArrayList<>());
}
return null;
}
}
@Component
public class AuthorizationFilter implements SecurityFilter {
@Override
public boolean doFilter(HttpServletRequest request, HttpServletResponse response, SecurityContext context) {
Authentication authentication = context.getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
response.setStatus(401);
return false;
}
// 检查权限
if (!hasPermission(authentication, request.getRequestURI())) {
response.setStatus(403);
return false;
}
return true;
}
private boolean hasPermission(Authentication authentication, String uri) {
// 简单的权限检查逻辑
return !uri.startsWith("/admin") || authentication.getAuthorities().stream()
.anyMatch(auth -> auth.getAuthority().equals("ROLE_ADMIN"));
}
}
5.2 Spring MVC的HandlerInterceptor
java
// 模拟Spring MVC的拦截器链
@Component
public class HandlerExecutionChain {
private final Object handler;
private final List<HandlerInterceptor> interceptors = new ArrayList<>();
public HandlerExecutionChain(Object handler) {
this.handler = handler;
}
public void addInterceptor(HandlerInterceptor interceptor) {
interceptors.add(interceptor);
}
public boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
for (HandlerInterceptor interceptor : interceptors) {
if (!interceptor.preHandle(request, response, handler)) {
// 前置处理返回false,中断执行
return false;
}
}
return true;
}
public void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView modelAndView) throws Exception {
for (int i = interceptors.size() - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors.get(i);
interceptor.postHandle(request, response, handler, modelAndView);
}
}
public void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception {
for (int i = interceptors.size() - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors.get(i);
interceptor.afterCompletion(request, response, handler, ex);
}
}
}
// 拦截器接口
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;
}
// 具体的拦截器
@Component
public class LoggingInterceptor implements HandlerInterceptor {
private static final ThreadLocal<Long> startTime = new ThreadLocal<>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
startTime.set(System.currentTimeMillis());
System.out.println("请求开始: " + request.getMethod() + " " + request.getRequestURI());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("请求处理完成,准备渲染视图");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
long duration = System.currentTimeMillis() - startTime.get();
System.out.println("请求完成,耗时: " + duration + "ms");
startTime.remove();
if (ex != null) {
System.out.println("请求处理异常: " + ex.getMessage());
}
}
}
@Component
public class PerformanceInterceptor implements HandlerInterceptor {
private static final long SLOW_REQUEST_THRESHOLD = 1000; // 1秒
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
request.setAttribute("startTime", System.currentTimeMillis());
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
Long startTime = (Long) request.getAttribute("startTime");
if (startTime != null) {
long duration = System.currentTimeMillis() - startTime;
if (duration > SLOW_REQUEST_THRESHOLD) {
System.out.println("警告: 慢请求 detected - " + request.getRequestURI() + " took " + duration + "ms");
}
}
}
}
6. 责任链模式的进阶用法
6.1 动态责任链
java
// 动态责任链:运行时可以动态添加、移除处理器
public class DynamicHandlerChain {
private List<Handler> handlers = new CopyOnWriteArrayList<>();
private volatile boolean frozen = false;
public void addHandler(Handler handler) {
if (frozen) {
throw new IllegalStateException("链已冻结,无法添加处理器");
}
handlers.add(handler);
// 按优先级排序
handlers.sort(Comparator.comparingInt(Handler::getPriority));
}
public boolean removeHandler(Handler handler) {
if (frozen) {
throw new IllegalStateException("链已冻结,无法移除处理器");
}
return handlers.remove(handler);
}
public void freeze() {
this.frozen = true;
}
public boolean process(Request request) {
for (Handler handler : handlers) {
if (handler.canHandle(request)) {
boolean result = handler.handle(request);
if (handler.isExclusive() && result) {
return true; // 独占处理器,处理成功即返回
}
}
}
return false;
}
// 获取链的统计信息
public ChainStats getStats() {
ChainStats stats = new ChainStats();
stats.setHandlerCount(handlers.size());
stats.setFrozen(frozen);
stats.setHandlerTypes(handlers.stream()
.map(h -> h.getClass().getSimpleName())
.collect(Collectors.toList()));
return stats;
}
}
// 处理器接口
public interface Handler {
boolean canHandle(Request request);
boolean handle(Request request);
int getPriority(); // 优先级,数值越小优先级越高
boolean isExclusive(); // 是否是独占处理器
}
// 链统计信息
@Data
public class ChainStats {
private int handlerCount;
private boolean frozen;
private List<String> handlerTypes;
}
6.2 责任链与策略模式结合
java
// 带策略的责任链
public class StrategicHandlerChain {
private Map<String, List<Handler>> chains = new HashMap<>();
private HandlerSelectionStrategy strategy;
public StrategicHandlerChain(HandlerSelectionStrategy strategy) {
this.strategy = strategy;
}
public void registerChain(String chainName, List<Handler> handlers) {
chains.put(chainName, new ArrayList<>(handlers));
}
public boolean process(Request request) {
String chainName = strategy.selectChain(request, chains.keySet());
List<Handler> chain = chains.get(chainName);
if (chain == null) {
throw new IllegalArgumentException("未知的责任链: " + chainName);
}
for (Handler handler : chain) {
if (handler.canHandle(request)) {
boolean result = handler.handle(request);
if (result && handler.isExclusive()) {
return true;
}
}
}
return false;
}
}
// 链选择策略
public interface HandlerSelectionStrategy {
String selectChain(Request request, Set<String> availableChains);
}
// 基于请求类型的策略
public class RequestTypeStrategy implements HandlerSelectionStrategy {
@Override
public String selectChain(Request request, Set<String> availableChains) {
if (request.getType().startsWith("API_")) {
return "apiChain";
} else if (request.getType().startsWith("BATCH_")) {
return "batchChain";
} else {
return "defaultChain";
}
}
}
// 基于性能的策略
public class PerformanceStrategy implements HandlerSelectionStrategy {
@Override
public String selectChain(Request request, Set<String> availableChains) {
if (request.isHighPriority()) {
return "fastChain"; // 快速链,处理器较少
} else {
return "comprehensiveChain"; // 全面链,处理器较多
}
}
}
7. 责任链模式 vs 其他模式
7.1 责任链模式 vs 装饰器模式
- 责任链模式:多个处理器按顺序处理请求,每个处理器决定是否处理或传递
- 装饰器模式:动态添加功能,所有装饰器都会处理请求
7.2 责任链模式 vs 命令模式
- 责任链模式:关注请求的处理流程,多个处理器协作
- 命令模式:将请求封装为对象,支持撤销、排队等操作
7.3 责任链模式 vs 策略模式
- 责任链模式:多个策略按顺序尝试,直到找到合适的
- 策略模式:在多个算法中选择一个执行
8. 总结与思考
8.1 责任链模式的优点
- 降低耦合度:请求发送者不需要知道具体的处理者
- 增强灵活性:可以动态改变处理链
- 简化对象:每个处理者只需关注自己的处理逻辑
- 符合开闭原则:新增处理者无需修改现有代码
8.2 责任链模式的缺点
- 请求可能未被处理:如果没有合适的处理者,请求可能无法被处理
- 性能影响:链过长可能影响性能
- 调试困难:请求的处理流程可能难以跟踪
- 可能产生循环引用:如果链配置不当,可能产生循环
8.3 设计思考
责任链模式的本质是**"处理流程的分解与传递"**。它通过将复杂的处理流程分解为多个简单的处理步骤,并将这些步骤组织成链,使得每个处理步骤都可以独立变化和复用。
深入思考的角度:
"责任链模式的核心价值在于它提供了一种解耦请求发送者和接收者的优雅方式。它让多个对象都有机会处理请求,从而实现了处理逻辑的灵活组合和动态配置。"
在实际应用中,责任链模式有很多优秀的实践:
- Java Servlet的Filter链
- Spring Security的安全过滤器链
- Spring MVC的拦截器链
- 日志框架的Appender链
从系统设计的角度看,责任链模式特别适合以下场景:
- 有多个对象可以处理请求,但具体由哪个对象处理在运行时确定
- 需要在不明确指定接收者的情况下向多个对象发送请求
- 需要动态指定处理请求的对象集合
最佳实践建议:
- 仔细设计处理者接口,确保接口的通用性
- 考虑使用建造者模式来构建责任链
- 为责任链提供合适的监控和调试支持
- 考虑处理链的性能影响,避免过长的链
- 为链提供合适的终止条件
使用场景判断:
- 适合:多步骤处理流程、动态处理顺序、需要解耦的场景
- 不适合:请求必须有明确处理者、性能要求极高的场景
下一篇预告:设计模式手册013 - 命令模式:如何将请求封装为对象,以便使用不同的请求、队列或日志来参数化其他对象?
版权声明:本文为CSDN博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。