设计模式之责任链模式

发布于:2025-04-16 ⋅ 阅读:(30) ⋅ 点赞:(0)

责任链模式(Chain of Responsibility Pattern)的实现核心在于通过链式结构将多个处理对象串联,使请求依次传递直至被处理。以下是其实现原理的详细解析,结合设计模式理论及实际框架(如 Mina、Netty、Java Filter)的应用场景:


一、责任链模式的核心结构

责任链模式由以下三个核心组件构成:

  1. Handler(抽象处理器)
    • 定义处理请求的接口,包含处理方法和设置下一个处理器的引用。
    • 示例代码(Java):

    public abstract class Handler {
        protected Handler nextHandler;
        public void setNext(Handler next) { this.nextHandler = next; }
        public abstract void handleRequest(Request request);
    }
    
  2. ConcreteHandler(具体处理器)
    • 实现 handleRequest 方法,包含具体处理逻辑。
    • 若当前处理器无法处理请求,则调用 nextHandler.handleRequest(request) 传递给下一个处理器。
    • 示例代码:

    public class ConcreteHandlerA extends Handler {
        @Override
        public void handleRequest(Request request) {
            if (request.getType().equals("TypeA")) {
                // 处理逻辑
            } else if (nextHandler != null) {
                nextHandler.handleRequest(request);
            }
        }
    }
    
  3. Client(客户端)
    • 构建责任链,将处理器按顺序链接,并向链头发送请求。
    • 示例代码:

    public class Client {
        public static void main(String[] args) {
            Handler handlerA = new ConcreteHandlerA();
            Handler handlerB = new ConcreteHandlerB();
            handlerA.setNext(handlerB);
            handlerA.handleRequest(new Request("TypeB"));
        }
    }
    

二、责任链的实现步骤

  1. 定义处理器接口
    • 明确处理请求的方法(如 handleRequest)和设置下一个处理器的方法(如 setNext)。

  2. 实现具体处理器
    • 每个具体处理器独立处理特定逻辑,并决定是否将请求传递给下一个处理器。
    关键逻辑
    条件判断:检查请求是否符合当前处理器的处理条件。
    终止或传递:若处理则终止链;否则调用 nextHandler.handleRequest(request)

  3. 构建责任链
    • 通过 setNext 方法将处理器按顺序链接,形成链式结构。
    • 示例链结构:

    HeadHandler → HandlerA → HandlerB → ... → TailHandler
    
  4. 触发链式处理
    • 客户端调用链头处理器的 handleRequest 方法,请求沿链传递。


三、责任链的变体与优化

  1. 单向链表 vs 双向链表
    单向链表:每个处理器仅持有下一个处理器的引用(如 Java Filter)。
    双向链表:处理器同时持有前驱和后继引用(如 Netty 的 ChannelPipeline),支持动态插入和删除。

  2. 链式构建模式
    • 结合建造者模式(Builder Pattern),通过链式调用简化链的构建。
    • 示例代码:

    new HandlerBuilder()
        .addHandler(new HandlerA())
        .addHandler(new HandlerB())
        .build();
    
  3. 默认处理器
    • 在链尾添加默认处理器,处理未被其他处理器处理的请求,避免请求丢失。


四、实际框架中的责任链实现

1. Java Servlet Filter

结构FilterChain 管理多个 Filter,每个 Filter 执行 doFilter() 方法后调用链中下一个 Filter
代码片段
java public class AuthenticationFilter implements Filter { private FilterChain chain; public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { // 认证逻辑 chain.doFilter(req, res); // 传递给下一个 Filter } }

2. Netty 的 ChannelPipeline

双向链表:每个 ChannelHandler 持有前驱和后继引用,支持动态插入。
事件传播:事件(如 channelRead)从头部传播到尾部,或反向传播。

3. Mina 的 IoFilterChain

链式调用IoFilter 通过 filterWrite() 方法将请求传递给下一个 Filter,最终由 TailFilter 写入通道。
关键类HeadFilter(链头)、TailFilter(链尾)用户历史对话


五、责任链模式的优缺点

优点 缺点
1. 解耦发送者与接收者:客户端无需知道具体处理者。
2. 灵活性强:动态调整链顺序或增减处理器。
3. 单一职责:每个处理器只关注自身逻辑。
1. 性能问题:长链可能导致延迟。
2. 调试复杂:链式传递可能增加追踪难度。
3. 循环引用风险:双向链表需避免死循环。

六、适用场景

  1. 多级审批流程(如报销系统)。
  2. 请求拦截与处理(如日志记录、权限校验)。
  3. 协议编解码(如 Mina 的 ProtocolCodecFilter用户历史对话
  4. 复杂业务流水线(如订单处理、数据清洗)。

七、实现示例(Java)

// 抽象处理器
public abstract class RequestHandler {
    protected RequestHandler nextHandler;

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

    public abstract void handle(Request request);
}

// 具体处理器A
public class AuthenticationHandler extends RequestHandler {
    @Override
    public void handle(Request request) {
        if (request.isAuthenticated()) {
            System.out.println("认证通过");
        } else if (nextHandler != null) {
            nextHandler.handle(request);
        }
    }
}

// 具体处理器B
public class LoggingHandler extends RequestHandler {
    @Override
    public void handle(Request request) {
        System.out.println("记录日志");
        if (nextHandler != null) {
            nextHandler.handle(request);
        }
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        RequestHandler authHandler = new AuthenticationHandler();
        RequestHandler logHandler = new LoggingHandler();
        authHandler.setNext(logHandler);

        Request request = new Request(false);
        authHandler.handle(request); // 输出:记录日志
    }
}

总结

责任链模式通过链式结构将请求处理逻辑解耦,其核心在于 处理器间的动态链接条件传递机制。实际应用中需根据场景选择单向或双向链表,并注意链长控制和调试优化。