责任链模式(Chain of Responsibility Pattern)

为了解决什么问题?

责任链模式的目的是为了将请求的发送者和接收者解耦。它允许多个处理器都有机会处理请求,将这些处理器连接成一条链,并沿着这条链传递请求,直到有一个处理器处理它为止。

通过这种方式,发送者不需要知道谁是请求的接收者,同时可以动态地改变链中的成员。

怎么用代码实现?

下面是Java代码示例,先定义抽象处理器,以及具体的处理器实现:

/**
 * 抽象处理器
 */
abstract class Handler {
    protected Handler successor;
    
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
    
    public abstract void handleRequest(String request);
}

/**
 * 处理器A
 */
class ConcreteHandlerA extends Handler {
    @Override
    public void handleRequest(String request) {
        if ("A".equals(request)) {
            System.out.println("ConcreteHandlerA handled the request.");
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

/**
 * 处理器B
 */
class ConcreteHandlerB extends Handler {
    @Override
    public void handleRequest(String request) {
        if ("B".equals(request)) {
            System.out.println("ConcreteHandlerB handled the request.");
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

然后,在调用前编排好责任链,再处理具体的请求:

/**
 * 客户端代码
 */
public class Client {
    public static void main(String[] args) {
        // 设置职责链上的处理对象
        Handler handlerA = new ConcreteHandlerA();
        Handler handlerB = new ConcreteHandlerB();
        handlerA.setSuccessor(handlerB);
        
        // 请求处理
        handlerA.handleRequest("A");
        handlerA.handleRequest("B");
    }
}

为什么可以解决这个问题?

责任链模式通过构建一条链来组织处理器,请求在链上传递,直到被处理。

因为请求发送者不需要知道具体的处理器,所以该模式降低了请求发送者与处理器之间的耦合度。同时,责任链模式提供了一种简单的方式来增加新的处理器或者重新排序现有处理器,提高了系统的灵活性和可扩展性。

责任链模式适用于哪些场景?

多个对象可以处理同一个请求时:可以使用责任链模式,客户端只需将请求发送到链上即可,无需关心请求的具体处理器。

动态指定处理对象集合:当在运行时需要改变处理请求的对象,或者不事先指定接收者时。

实施隐式接收链:当处理一个请求的处理不必显式地设定,而是每个处理器自己选择是否将请求传递给下一个处理器。

不明确特定请求的处理器:当你希望请求不被特定接收者直接处理,而是有多个对象中的一个来处理时。

多个对象决定如何处理请求:当多个对象可以处理请求,且具体处理器是在运行时自动确定时,如基于运行时条件动态决定处理器。

广播通信:当需要向所有的对象发出一个请求,而又不想显式指定接收者时,责任链可作为一种广播机制。

责任链模式在开源代码的实际应用案例有:

Java Servlet Filters:Servlet过滤器就是一种责任链模式的实现。每个过滤器可以决定是完成对请求的处理,还是将请求传递给责任链中的下一过滤器。

Logback中的拦截器链:在Logback这个日志框架中,日志事件可以经过多个拦截器进行处理,每个拦截器可以对事件进行加工,或者阻止事件继续传递。

Spring Security中的过滤器链:Spring Security使用责任链模式来处理安全过滤器,请求在通过多个安全过滤器链前行进,每个过滤器执行特定的安全检查。

Apache Camel路由器:Apache Camel使用责任链模式构建复杂的消息路由处理链,请求(消息)通过一系列处理器进行处理,每个处理器完成特定功能后可能将消息传递给下一个处理器。

责任链模式有哪些优点和缺点?

责任链模式提供一种将请求的发送者和接收者进行解耦的模式。它通过给多个对象处理请求的机会,增强了系统的灵活性,有助于代码的维护和扩展。

然而,责任链模式可能会导致请求不被处理(如果链没有被正确配置)以及性能问题(如果链较长或处理比较复杂)。

因此,责任链应当适用于预期请求会在链中被处理,并且处理器数量合理的情况下使用。

优点:

降低耦合度:它解耦了请求发送者和N个接收者之间的复杂关系,使得链中的对象不需要知道链的结构。因此,增加或删除处理器或者改变处理器顺序变得更加容易。

增强给定请求的处理器的灵活性:通过改变链内成员或者重新重新排序,可以动态地改变处理器间的关系。

增加新的请求处理类方便:扩展新的处理类不影响其他的类,符合开放-封闭原则。

缺点:

不能保证请求一定被接收:一个请求可能最终未被任何处理器对象处理,客户端也不会得到明确的反馈。

对链中请求处理器的遍历:如果链很长,请求的处理可能涉及多个处理对象,会增加处理延迟,并影响性能。

维护链可能需要额外开销:链的构建与维护可能需要消耗资源,特别是在动态改变链结构时。

责任链模式是一种强大的行为设计模式,通过解耦发送者和接收者,它提供了请求处理的灵活性和扩展性。然而,设计责任链时应当注意其可能带来的性能考量和处理的不确定性,适当的使用场景和良好的设计是确保该模式有效运用的关键。

———————————这是分割线———————————

欢迎添加博主vx深入交流:
博主微信

Logo

一起探索未来云端世界的核心,云原生技术专区带您领略创新、高效和可扩展的云计算解决方案,引领您在数字化时代的成功之路。

更多推荐