责任链模式(Chain of Responsibility Pattern)是我在Java开发中最常使用的行为型设计模式之一。它特别适合处理那些需要多个对象按顺序处理同一请求的场景。让我们从一个真实案例开始理解这个模式的价值。
假设我们正在开发一个电商平台的订单处理系统。订单需要经过以下检查:
传统实现可能是这样的:
java复制public void processOrder(Order order) {
if (!checkInventory(order)) {
throw new RuntimeException("库存不足");
}
if (!checkUserCredit(order.getUser())) {
throw new RuntimeException("信用不足");
}
if (!validatePayment(order.getPayment())) {
throw new RuntimeException("支付方式无效");
}
applyPromotions(order);
}
这种写法存在几个明显问题:
使用责任链模式重构后,代码变得清晰且可扩展:
java复制public interface OrderHandler {
void setNext(OrderHandler next);
void handle(Order order);
}
public class InventoryHandler implements OrderHandler {
private OrderHandler next;
@Override
public void setNext(OrderHandler next) {
this.next = next;
}
@Override
public void handle(Order order) {
if (!checkInventory(order)) {
throw new RuntimeException("库存不足");
}
if (next != null) {
next.handle(order);
}
}
}
// 其他Handler类似...
责任链模式的标准实现包含三个关键角色:
java复制public abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(Request request);
protected void forward(Request request) {
if (successor != null) {
successor.handleRequest(request);
}
}
}
java复制public class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(Request request) {
if (canHandle(request)) {
// 处理逻辑
} else {
forward(request);
}
}
private boolean canHandle(Request request) {
// 判断条件
}
}
java复制Handler handler1 = new ConcreteHandlerA();
Handler handler2 = new ConcreteHandlerB();
handler1.setSuccessor(handler2);
handler1.handleRequest(new Request());
在实际开发中,我们经常会根据需求对标准模式进行变体实现:
java复制public interface Interceptor {
boolean intercept(Request request);
}
public class InterceptorChain {
private List<Interceptor> interceptors = new ArrayList<>();
public void addInterceptor(Interceptor interceptor) {
interceptors.add(interceptor);
}
public boolean process(Request request) {
for (Interceptor interceptor : interceptors) {
if (!interceptor.intercept(request)) {
return false;
}
}
return true;
}
}
java复制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 void addFilter(Filter filter) {
filters.add(filter);
}
public void doFilter(Request request, Response response) {
if (index < filters.size()) {
Filter filter = filters.get(index++);
filter.doFilter(request, response, this);
}
}
}
Spring框架中大量使用了责任链模式,理解这些实现能帮助我们更好地应用该模式。
java复制public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
// 认证逻辑
return true; // 继续链
}
}
// 配置
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/api/**");
}
}
Spring Security的核心就是一条责任链:
java复制http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.addFilterBefore(new CustomFilter(), UsernamePasswordAuthenticationFilter.class);
AOP的拦截器链也是责任链的典型应用:
java复制@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
// 前置通知
}
@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))",
returning = "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
// 返回通知
}
}
对于耗时操作,我们可以实现异步责任链:
java复制public interface AsyncHandler {
CompletableFuture<Void> handleAsync(Request request);
}
public class AsyncChain {
private List<AsyncHandler> handlers = new ArrayList<>();
public CompletableFuture<Void> execute(Request request) {
CompletableFuture<Void> future = CompletableFuture.completedFuture(null);
for (AsyncHandler handler : handlers) {
future = future.thenCompose(v -> handler.handleAsync(request));
}
return future;
}
}
某些场景下我们需要提前终止链的执行:
java复制public abstract class Handler {
protected Handler next;
public enum Result {
CONTINUE, BREAK, RETURN
}
public Result handle(Request request) {
Result result = doHandle(request);
if (result == Result.CONTINUE && next != null) {
return next.handle(request);
}
return result;
}
protected abstract Result doHandle(Request request);
}
对于频繁调用的责任链,可以考虑缓存处理结果:
java复制public class CachedHandler implements Handler {
private Handler delegate;
private Cache<Request, Response> cache;
@Override
public Response handle(Request request) {
Response response = cache.get(request);
if (response == null) {
response = delegate.handle(request);
cache.put(request, response);
}
return response;
}
}
责任链模式常与其他模式结合使用,产生更强大的效果。
java复制public class HandlerFactory {
public static Handler createChain(Config config) {
Handler first = null;
Handler previous = null;
for (HandlerConfig hc : config.getHandlers()) {
Handler current = createHandler(hc);
if (first == null) {
first = current;
}
if (previous != null) {
previous.setNext(current);
}
previous = current;
}
return first;
}
}
java复制public class DynamicHandler implements Handler {
private Map<Condition, Handler> strategyMap = new HashMap<>();
@Override
public void handle(Request request) {
for (Entry<Condition, Handler> entry : strategyMap.entrySet()) {
if (entry.getKey().matches(request)) {
entry.getValue().handle(request);
return;
}
}
// 默认处理或传递
}
}
java复制public class ObservableHandler implements Handler {
private Handler delegate;
private List<HandlerListener> listeners = new ArrayList<>();
@Override
public void handle(Request request) {
notifyBefore(request);
try {
delegate.handle(request);
notifySuccess(request);
} catch (Exception e) {
notifyFailure(request, e);
throw e;
}
}
}
问题1:循环引用导致栈溢出
java复制Handler h1 = new HandlerA();
Handler h2 = new HandlerB();
h1.setNext(h2);
h2.setNext(h1); // 循环引用!
解决方案:在setNext方法中添加循环检测
java复制public void setNext(Handler next) {
if (isInChain(next, this)) {
throw new IllegalStateException("循环引用检测");
}
this.next = next;
}
private boolean isInChain(Handler target, Handler current) {
while (current != null) {
if (current == target) return true;
current = current.next;
}
return false;
}
问题2:内存泄漏
长生命周期的责任链可能持有大量对象引用。
解决方案:提供clear方法或使用弱引用
java复制public void clear() {
this.next = null;
// 其他清理
}
问题3:调试困难
责任链的跳转使调用栈变深。
解决方案:添加唯一标识和日志
java复制public abstract class Handler {
private final String id = UUID.randomUUID().toString();
public void handle(Request request) {
log.debug("Handler {} processing request {}", id, request);
// ...
}
}
java复制public class FastFailHandler implements Handler {
@Override
public void handle(Request request) {
if (request.isInvalid()) {
throw new FastFailException("请求无效");
}
next.handle(request);
}
}
责任链的测试需要特别关注:
java复制@Test
public void testChainOrder() {
Handler chain = createChain();
TestRequest request = new TestRequest();
chain.handle(request);
assertEquals("A->B->C", request.getProcessTrace());
}
@Test
public void testShortCircuit() {
Handler chain = createChain();
TestRequest request = new TestRequest();
request.setShouldStopAtB(true);
chain.handle(request);
assertEquals("A->B", request.getProcessTrace());
}
java复制public class DynamicChain implements Handler {
private List<Handler> handlers = new CopyOnWriteArrayList<>();
public void addHandler(Handler handler) {
handlers.add(handler);
}
public void removeHandler(Handler handler) {
handlers.remove(handler);
}
@Override
public void handle(Request request) {
for (Handler handler : handlers) {
handler.handle(request);
}
}
}
java复制public class BranchHandler implements Handler {
private Handler successChain;
private Handler failureChain;
@Override
public void handle(Request request) {
if (checkCondition(request)) {
successChain.handle(request);
} else {
failureChain.handle(request);
}
}
}
java复制public class BacktrackingHandler implements Handler {
private Handler next;
@Override
public void handle(Request request) {
try {
if (next != null) {
next.handle(request);
}
postHandle(request);
} catch (Exception e) {
rollback(request);
throw e;
}
}
private void postHandle(Request request) {
// 后置处理
}
private void rollback(Request request) {
// 回滚逻辑
}
}
在实际项目中,责任链模式的价值在于它提供了一种松耦合的方式来组织处理逻辑。从我多年的开发经验来看,合理使用责任链模式可以显著提高代码的可维护性和扩展性。特别是在处理复杂业务流程时,将大块的if-else逻辑拆分为责任链,不仅使代码更清晰,也更容易应对需求变更。