一、什么是责任链模式

想象一下你在一家大型企业工作,需要申请一笔采购经费。这张申请单需要经过部门经理、财务总监、副总经理层层审批,每个环节都可能修改或驳回请求。这种"流水线式"的处理方式,就是责任链模式在现实生活中的体现。

在编程世界里,责任链模式(Chain of Responsibility)是一种行为设计模式,它允许你将请求沿着处理者链进行传递。每个处理者都可以决定是否处理该请求,或者将请求传递给链中的下一个处理者。这种模式最大的好处是解耦了请求发送者和接收者,让多个对象都有机会处理请求。

二、责任链模式的结构

让我们用Java代码来解剖这个模式的核心结构。假设我们要实现一个Web请求过滤器链:

// 1. 首先定义一个处理请求的抽象类
public abstract class Handler {
    protected Handler nextHandler;  // 下一个处理者
    
    // 设置下一个处理者
    public void setNext(Handler handler) {
        this.nextHandler = handler;
    }
    
    // 处理请求的抽象方法
    public abstract void handleRequest(Request request);
}

// 2. 实现具体的处理者
public class AuthenticationHandler extends Handler {
    @Override
    public void handleRequest(Request request) {
        if (request.getToken() == null) {
            System.out.println("认证失败:缺少token");
            return;
        }
        System.out.println("认证通过");
        
        // 传递给下一个处理者
        if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

public class AuthorizationHandler extends Handler {
    @Override
    public void handleRequest(Request request) {
        if (!request.getUserRole().equals("admin")) {
            System.out.println("授权失败:权限不足");
            return;
        }
        System.out.println("授权通过");
        
        if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

// 3. 请求对象
public class Request {
    private String token;
    private String userRole;
    
    // 省略getter/setter
}

这个结构展示了责任链模式的三个关键部分:

  • 抽象处理者(Handler):定义处理请求的接口和设置下一个处理者的方法
  • 具体处理者(AuthenticationHandler等):实现具体的处理逻辑
  • 客户端代码:构建处理链并触发请求

三、过滤器链的完整实现

让我们用一个更完整的Web请求过滤器示例来演示。假设我们要处理一个HTTP请求,需要经过以下过滤步骤:

  1. IP黑名单检查
  2. 用户认证
  3. 请求限流
  4. 敏感词过滤
// 1. 定义过滤器接口
public interface Filter {
    void doFilter(HttpRequest request, FilterChain chain);
}

// 2. 实现过滤器链
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) {
        if (index < filters.size()) {
            Filter filter = filters.get(index++);
            filter.doFilter(request, this);
        } else {
            // 所有过滤器通过,执行业务逻辑
            System.out.println("执行业务处理...");
        }
    }
}

// 3. 实现具体过滤器
public class IpFilter implements Filter {
    @Override
    public void doFilter(HttpRequest request, FilterChain chain) {
        if (isInBlackList(request.getIp())) {
            System.out.println("IP被列入黑名单");
            return;
        }
        System.out.println("IP检查通过");
        chain.doFilter(request);
    }
    
    private boolean isInBlackList(String ip) {
        // 模拟黑名单检查
        return "192.168.1.100".equals(ip);
    }
}

public class AuthFilter implements Filter {
    @Override
    public void doFilter(HttpRequest request, FilterChain chain) {
        if (request.getToken() == null) {
            System.out.println("未授权请求");
            return;
        }
        System.out.println("认证通过");
        chain.doFilter(request);
    }
}

// 4. 客户端使用
public class Client {
    public static void main(String[] args) {
        FilterChain chain = new FilterChain()
            .addFilter(new IpFilter())
            .addFilter(new AuthFilter())
            .addFilter(new RateLimitFilter())
            .addFilter(new SensitiveWordFilter());
            
        HttpRequest request = new HttpRequest("192.168.1.1", "token123");
        chain.doFilter(request);
    }
}

这个实现展示了责任链模式的动态性 - 我们可以随时添加或移除过滤器,而不需要修改其他过滤器的代码。

四、Spring中的责任链实践

在Spring框架中,责任链模式被广泛应用。让我们看看如何在Spring中实现一个过滤器链:

// 1. 定义过滤器接口
public interface OrderFilter {
    void filter(Order order, FilterChain chain);
    
    int getOrder();  // 用于确定过滤器的执行顺序
}

// 2. 实现过滤器链
@Service
public class OrderFilterChain {
    @Autowired
    private List<OrderFilter> filters;
    
    public void doFilter(Order order) {
        // 按优先级排序
        List<OrderFilter> sortedFilters = filters.stream()
            .sorted(Comparator.comparingInt(OrderFilter::getOrder))
            .collect(Collectors.toList());
            
        new DefaultFilterChain(sortedFilters).doFilter(order);
    }
    
    private static class DefaultFilterChain {
        private final List<OrderFilter> filters;
        private int position = 0;
        
        public DefaultFilterChain(List<OrderFilter> filters) {
            this.filters = filters;
        }
        
        public void doFilter(Order order) {
            if (position < filters.size()) {
                OrderFilter filter = filters.get(position++);
                filter.filter(order, this);
            } else {
                // 所有过滤器通过
                System.out.println("订单处理完成");
            }
        }
    }
}

// 3. 实现具体过滤器
@Service
public class InventoryCheckFilter implements OrderFilter {
    @Override
    public void filter(Order order, FilterChain chain) {
        if (!checkInventory(order)) {
            throw new RuntimeException("库存不足");
        }
        chain.doFilter(order);
    }
    
    @Override
    public int getOrder() {
        return 1;  // 第一个执行
    }
}

Spring的这种实现方式充分利用了IoC容器的优势,通过自动注入和排序简化了过滤器链的构建过程。

五、应用场景分析

责任链模式特别适合以下场景:

  1. Web请求处理:如Servlet Filter、Spring Interceptor等
  2. 审批流程:如请假审批、采购审批等多级审批系统
  3. 日志处理:不同级别的日志由不同的处理器处理
  4. 错误处理:异常捕获链,每个处理器尝试处理特定类型的异常
  5. 数据验证:多层次的校验规则

比如在电商系统中,下单流程可能需要:

  • 验证用户身份
  • 检查商品库存
  • 验证优惠券有效性
  • 计算运费
  • 风险控制检查

每个步骤都可以是一个独立的处理器,通过责任链串联起来。

六、技术优缺点

优点:

  1. 解耦:发送者不需要知道具体由哪个处理器处理请求
  2. 灵活性:可以动态添加、删除或重新排序处理器
  3. 单一职责:每个处理器只关注自己的处理逻辑
  4. 可扩展性:新增处理器不需要修改现有代码

缺点:

  1. 性能:长链可能导致性能下降
  2. 调试困难:请求可能被链中的多个处理器处理,调试时难以跟踪
  3. 不确定性:请求可能最终没有被任何处理器处理

七、注意事项

  1. 控制链的长度:过长的处理链会影响性能,必要时可以考虑其他模式
  2. 避免循环引用:处理器之间相互引用可能导致无限循环
  3. 明确终止条件:确保请求不会无限传递下去
  4. 错误处理:考虑处理器抛出异常时的处理策略
  5. 线程安全:如果链在运行时可能被修改,需要考虑线程安全问题

八、总结

责任链模式是处理复杂业务流程的利器,它像流水线一样将处理逻辑分解为多个独立的步骤,每个步骤专注于自己的职责。在Java生态中,从Servlet Filter到Spring Interceptor,责任链模式无处不在。

当你的系统需要处理需要经过多个检查或处理步骤的请求时,不妨考虑使用责任链模式。它能让你的代码更加灵活、可维护,也更容易应对未来的需求变化。记住,好的架构不是一开始就完美无缺的,而是能够优雅地应对变化。