侧边栏壁纸
博主头像
牧云

怀璧慎显,博识谨言。

  • 累计撰写 96 篇文章
  • 累计创建 11 个标签
  • 累计收到 8 条评论

目 录CONTENT

文章目录

责任链模式详解:结合过滤器链的深入解析

秋之牧云
2025-11-21 / 0 评论 / 0 点赞 / 10 阅读 / 0 字

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,其核心思想是:将请求的处理者解耦,让请求沿着链传递,直到被某个处理者处理或链结束。它通过链式结构实现灵活、可扩展的请求处理逻辑,广泛应用于各种场景,如审批流程、过滤器链、拦截器链等。


一、责任链模式的核心要素

1. 请求(Request)

  • 请求是客户端发起的事件或数据,例如:HTTP 请求、请假申请、订单校验等。

  • 它需要被多个处理者依次处理,直到被某个处理者“终结”。

2. 处理者(Handler)

  • 每个处理者是一个对象,负责处理请求的一部分逻辑。

  • 处理者通常包含以下功能:

  • 处理请求:判断是否能处理当前请求。

  • 传递请求:如果不能处理,则将请求传递给链中的下一个处理者。

3. 链(Chain)

  • 链是由多个处理者按顺序组成的结构。

  • 链的构建方式可以是静态的(如配置文件)或动态的(如代码中手动拼接)。

4. 终止条件

  • 链的终点可能是:

  • 某个处理者处理了请求(如审批通过)。

  • 所有处理者都无法处理请求(如拒绝审批)。


二、责任链模式的实现结构

1. 抽象处理者(Handler)

定义统一的接口,包含处理请求的方法和传递请求的方法。

// 抽象处理者接口
public interface Handler {
    void setNext(Handler next); // 设置下一个处理者
    void handleRequest(Request request); // 处理请求
}

2. 具体处理者(Concrete Handlers)

实现具体的处理逻辑,决定是否处理请求或传递给下一个处理者。

// 具体处理者1:主管
public class Manager implements Handler {
    private Handler next;

    public void setNext(Handler next) {
        this.next = next;
    }

    public void handleRequest(Request request) {
        if (request.getDays() <= 1) {
            System.out.println("主管批准 " + request.getName() + " 的 " + request.getDays() + " 天请假");
        } else if (next != null) {
            System.out.println("主管转交经理处理 " + request.getName() + " 的 " + request.getDays() + " 天请假");
            next.handleRequest(request);
        }
    }
}

// 具体处理者2:经理
public class Manager2 implements Handler {
    private Handler next;

    public void setNext(Handler next) {
        this.next = next;
    }

    public void handleRequest(Request request) {
        if (request.getDays() <= 3) {
            System.out.println("经理批准 " + request.getName() + " 的 " + request.getDays() + " 天请假");
        } else if (next != null) {
            System.out.println("经理转交总监处理 " + request.getName() + " 的 " + request.getDays() + " 天请假");
            next.handleRequest(request);
        }
    }
}

3. 客户端(Client)

构建链的结构并发送请求。

// 客户端代码
public class Client {
    public static void main(String[] args) {
        // 构建责任链
        Handler manager = new Manager();
        Handler manager2 = new Manager2();
        Handler director = new Director();

        manager.setNext(manager2);
        manager2.setNext(director);

        // 提交请求
        manager.handleRequest(new Request("张三", 2));  // 经理批准
        manager.handleRequest(new Request("李四", 5));  // 总监批准
        manager.handleRequest(new Request("王五", 10)); // 总监拒绝
    }
}

三、过滤器链(Filter Chain)作为责任链模式的典型应用

在 Web 开发中,过滤器链(Filter Chain)是责任链模式的典型应用。Servlet 容器(如 Tomcat)通过过滤器链实现对请求的预处理和后处理。

1. 过滤器链的结构

  • 每个过滤器(Filter)是一个处理者。

  • 请求按配置顺序依次经过每个过滤器,直到目标资源(如 Servlet)。

2. 过滤器链的执行流程

  1. 请求到达:容器调用第一个过滤器的 doFilter 方法。

  2. 过滤器处理

  • 如果过滤器能处理请求(如认证通过),调用 chain.doFilter 传递请求。

  • 如果不能处理(如认证失败),直接返回响应。

  1. 目标资源处理:请求到达目标资源(如 Servlet)。

  2. 响应返回:响应按相反顺序返回,依次经过每个过滤器的后续逻辑(如日志记录)。

3. 过滤器链的代码示例

// 过滤器1:认证过滤器
public class AuthFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        if (isAuthenticated(request)) {
            chain.doFilter(request, response); // 传递到下一个过滤器
        } else {
            ((HttpServletResponse) response).sendRedirect("login.jsp");
        }
    }
}

// 过滤器2:日志过滤器
public class LogFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        System.out.println("请求到达日志过滤器");
        chain.doFilter(request, response); // 传递到下一个过滤器
        System.out.println("请求处理完成");
    }
}

4. 过滤器链的配置(web.xml)

<filter>
    <filter-name>AuthFilter</filter-name>
    <filter-class>com.example.AuthFilter</filter-class>
</filter>
<filter>
    <filter-name>LogFilter</filter-name>
    <filter-class>com.example.LogFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AuthFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>LogFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

四、责任链模式与过滤器链的对比

特性

责任链模式

过滤器链(Filter Chain)

适用范围

通用,适用于任何需要链式处理的场景

专用于 Web 请求处理(如 Servlet)

实现方式

手动构建链的结构,处理逻辑由开发者定义

由框架自动管理,开发者只需编写 Filter 逻辑

控制权

完全由开发者控制

由框架控制,开发者无法直接控制链的结构

处理逻辑

可以是任意业务逻辑(如审批、日志等)

通常用于预处理和后处理(如编码、权限)


五、责任链模式的优缺点

优点

  1. 解耦:发送者与处理者解耦,请求的处理逻辑由链上的节点决定。

  2. 灵活扩展:可以动态添加或移除处理者,无需修改现有代码。

  3. 动态组合:可以在运行时动态调整处理者顺序。

缺点

  1. 链过长可能导致性能问题:过多的处理者会增加请求处理时间。

  2. 调试复杂:请求的处理路径可能难以追踪(尤其在多个处理者嵌套时)。


六、责任链模式的实际应用场景

  1. 审批流程

  • 请假、报销等请求按层级传递,直到被某个审批人处理。

  • 示例:主管 → 经理 → 总监。

  1. 事件处理系统

  • GUI 事件(如点击、键盘输入)按层级传递,直到被某个组件处理。

  1. 业务规则校验

  • 订单验证、支付校验等,按规则顺序检查,直到满足条件或失败。

  1. Web 过滤器链

  • 对请求进行预处理(如认证、日志)和后处理(如响应编码)。


七、责任链模式的设计原则

  1. 单一职责原则

  • 每个处理者只关注自己的职责,避免逻辑混杂。

  1. 开闭原则

  • 可以通过新增处理者扩展功能,无需修改现有代码。

  1. 依赖倒置原则

  • 处理者之间通过接口通信,不直接依赖具体实现。


八、实际开发中的注意事项

  1. 避免链过长

  • 链过长可能导致性能问题,需合理设计处理者的数量。

  1. 确保有终止节点

  • 防止请求无限传递,例如在最后一个处理者中明确终止逻辑。

  1. 动态调整链的结构

  • 在运行时动态添加或移除处理者,增强灵活性。

  1. 日志和调试

  • 在处理者中添加日志,便于追踪请求的处理路径。


九、总结

责任链模式通过链式结构实现请求的灵活处理,其核心思想是让请求自己寻找合适的处理者。在 Web 开发中,过滤器链是责任链模式的典型应用,通过链式结构实现请求的预处理和后处理。无论是审批流程、事件处理,还是 Web 过滤器链,责任链模式都能提供解耦、灵活、可扩展的解决方案。

0

评论区