网站Logo Ilren 小记

Java设计模式-责任链模式

jack
15
2023-05-07

责任链模式(Chain of Responsibility Pattern):请求处理的流水线

模式简介
责任链模式是一种行为型设计模式,允许你将请求沿着处理链传递,直到有一个处理者能够处理它。
就像公司审批流程:员工提交申请后,经过经理→总监→CEO的逐级审批,每个层级都有明确的处理权限。

📦 应用场景

  • 多级权限校验(如Spring Security过滤器链)

  • 请求拦截/预处理(如Servlet Filter)

  • 日志记录管道(如Log4j2的Appender链)

  • 工作流审批系统

  • 异常处理流程(try-catch嵌套)

  • 游戏中的事件处理系统

🧠 核心实现思路

  1. Handler(处理者):定义处理请求的接口

  2. ConcreteHandler(具体处理者):实现具体处理逻辑

  3. Client(客户端):组装责任链并触发请求

🧱 责任链模式的多种实现方式

1. 经典实现(链表式)

// 处理者接口
interface Handler {
    void setNext(Handler handler);
    void handle(Request request);
}

// 抽象处理者
abstract class AbstractHandler implements Handler {
    private Handler next;
    
    public void setNext(Handler handler) {
        this.next = handler;
    }
    
    protected void passToNext(Request request) {
        if (next != null) next.handle(request);
    }
    
    abstract boolean canHandle(Request request);
}

// 具体处理者
class AuthHandler extends AbstractHandler {
    @Override
    public void handle(Request request) {
        if (canHandle(request)) {
            System.out.println("进行权限校验...");
            // 具体处理逻辑
        } else {
            passToNext(request);
        }
    }
    
    @Override
    boolean canHandle(Request request) {
        return request.getType() == RequestType.AUTH;
    }
}

// 客户端构建责任链
Handler chain = new AuthHandler();
chain.setNext(new LogHandler());
chain.setNext(new BusinessHandler());
chain.handle(request);

2. 函数式实现(Java8+)

// 定义处理函数接口
@FunctionalInterface
interface Handler {
    boolean handle(Request request);
}

// 责任链构建工具
class ChainBuilder {
    private List<Handler> handlers = new ArrayList<>();
    
    public ChainBuilder addHandler(Handler handler) {
        handlers.add(handler);
        return this;
    }
    
    public void execute(Request request) {
        for (Handler handler : handlers) {
            if (handler.handle(request)) break;
        }
    }
}

// 使用Lambda构建
new ChainBuilder()
    .addHandler(req -> { /* 处理逻辑1 */ })
    .addHandler(req -> { /* 处理逻辑2 */ })
    .execute(request);

3. Spring风格实现(注解驱动)

// 自定义注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface ChainOrder {
    int value();
}

// 抽象处理器
public interface OrderHandler {
    void handle(OrderContext context);
}

// 具体处理器(自动排序)
@ChainOrder(1)
@Component
class ValidationHandler implements OrderHandler {
    @Override
    public void handle(OrderContext context) {
        if (!isValid(context.getOrder())) {
            throw new RuntimeException("校验失败");
        }
    }
}

// 责任链执行器
@Service
public class OrderProcessor {
    @Autowired
    private List<OrderHandler> handlers; // Spring自动注入并排序
    
    public void process(Order order) {
        OrderContext context = new OrderContext(order);
        for (OrderHandler handler : handlers) {
            handler.handle(context);
        }
    }
}

💎 最佳实践推荐

动态可配置责任链

// 配置化定义处理链
@Configuration
public class HandlerConfig {
    @Bean
    public HandlerChain securityChain() {
        return new HandlerChain()
            .addHandler(new IPFilter())
            .addHandler(new RateLimiter())
            .addHandler(new AuthHandler());
    }
}

// 支持热更新
public class HandlerChain {
    private volatile List<Handler> handlers;
    
    public synchronized void reload(List<Handler> newHandlers) {
        this.handlers = List.copyOf(newHandlers);
    }
}

中断与回滚机制

abstract class TransactionalHandler implements Handler {
    @Override
    public final void handle(Request request) {
        try {
            doHandle(request);
        } catch (Exception e) {
            rollback(request);
            throw e;
        }
    }
    
    abstract void doHandle(Request request);
    abstract void rollback(Request request);
}

💣 常见问题与解决方案

问题1:如何避免请求未被处理?

解决方案

  • 设置默认处理器(兜底处理)

  • 使用Optional包装处理结果

问题2:处理器之间需要共享数据?

解决方案

  • 使用上下文对象(如RequestContext

  • ThreadLocal存储线程级共享数据

问题3:如何监控处理性能?

解决方案

  • 责任链包装器(AOP风格)

class MonitoredHandler implements Handler {
    private final Handler delegate;
    
    @Override
    public void handle(Request request) {
        long start = System.nanoTime();
        delegate.handle(request);
        Metrics.record(delegate.getClass(), System.nanoTime()-start);
    }
}

📊 模式对比

实现方式

优点

缺点

适用场景

经典链表式

结构清晰

需手动维护链

简单固定流程

函数式

灵活组合

调试困难

动态流程配置

Spring注解式

自动装配

依赖容器

企业级应用

📚 实际应用案例

  1. Servlet Filter Chain

    @WebFilter("/*")
    public class LogFilter implements Filter {
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
            // 前置处理
            chain.doFilter(req, res); // 传递给下一个过滤器
            // 后置处理
        }
    }
  2. Spring Security过滤器链

    http.addFilterBefore(new CustomFilter(), BasicAuthenticationFilter.class);
  3. Netty的ChannelPipeline

    pipeline.addLast("decoder", new StringDecoder());
    pipeline.addLast("handler", new BusinessHandler());

🎯 总结建议

  1. 链长控制:建议不超过10个处理器(性能考量)

  2. 异常处理:明确每个处理器的失败策略

  3. 动态配置:结合配置中心实现热更新

  4. 监控埋点:记录每个处理器的执行耗时

  5. 短路优化:支持快速失败(如权限校验不通过立即终止)

动物装饰