设计模式——责任链模式(Chain)

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许请求在对象链中进行传递。直到链中的某个对象决定处理该请求为止。换句话说,它将请求的发送者和接收者解耦,让多个对象都有可能处理这个请求,从而避免请求的发送者直接将请求发送到特定的接收者。

责任链模式包含以下几个角色:

  1. Handler(处理者):定义了处理请求的接口,通常包含一个抽象方法或者一个处理请求的抽象类。每个处理者都知道自己的后继者(下一个处理者),如果自己不能处理该请求,则将其转发给后继者。
  2. ConcreteHandler(具体处理者):实现了Handler接口,并对请求进行实际处理。每个具体处理者都能够处理一些特定的请求类型,如果自己不能处理该请求,则将其转发给后继者。
  3. Client(客户端):创建链条的起点,向链条头部的处理者发送请求。

责任链模式的结构相对简单,主要包括Handler(处理者)和Client(客户端)。在Handler中,通常会定义两个方法:一个是处理请求的handleRequest()方法,另一个是设置后继节点的setSuccessor()方法。Client类则负责创建责任链的头部,即第一个ConcreteHandler。

责任链模式的特点主要有:

  • 链上的每个对象都有机会处理请求。
  • 链上的每个对象都持有下一个要处理对象的引用。
  • 链上的某个对象无法处理当前请求,那么它会把相同的请求传给下一个对象。

责任链模式有两种类型:纯责任链模式和不纯的责任链模式。纯责任链模式要求一个类要么承担责任处理请求,要么将请求踢给下一个处理类。而不纯的责任链模式则允许一个类承担一部分责任,并将剩余的责任踢给下一个处理类。

责任链模式的应用场景包括但不限于:

  • 认证和授权:可以将认证和授权的逻辑封装到多个处理器中,并按照一定的顺序组成一个责任链。当用户发送请求时,责任链中的处理器依次进行认证和授权操作。
  • 日志记录:将日志记录的逻辑封装到多个处理器中,并按照一定的顺序组成一个责任链。当需要记录日志时,请求会沿着责任链传递,每个处理器都可以选择是否记录日志,以及记录日志的方式和内容。
  • 异常处理:将不同类型的异常处理逻辑分别封装到不同的处理器中,并按照一定的顺序组成一个责任链。当系统出现异常时,请求会沿着责任链传递,每个处理器都可以选择是否处理该异常,以及如何处理。

以下是一个使用Java编写的责任链模式的简单示例。在这个例子中,我们有一个Handler接口和两个实现了该接口的ConcreteHandler类。我们还有一个Client类,用于发送请求到责任链的头部。

java 复制代码
// Handler接口
public interface Handler {
    void handleRequest(String request);
    void setSuccessor(Handler successor);
}

// ConcreteHandlerA类
public class ConcreteHandlerA implements Handler {
    private Handler successor;

    @Override
    public void handleRequest(String request) {
        if (request.startsWith("A")) {
            System.out.println("ConcreteHandlerA handled " + request);
        } else {
            if (successor != null) {
                successor.handleRequest(request);
            } else {
                System.out.println("No handler for " + request);
            }
        }
    }

    @Override
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
}

// ConcreteHandlerB类
public class ConcreteHandlerB implements Handler {
    private Handler successor;

    @Override
    public void handleRequest(String request) {
        if (request.startsWith("B")) {
            System.out.println("ConcreteHandlerB handled " + request);
        } else {
            if (successor != null) {
                successor.handleRequest(request);
            } else {
                System.out.println("No handler for " + request);
            }
        }
    }

    @Override
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
}

// Client类
public class Client {
    public static void main(String[] args) {
        Handler handlerA = new ConcreteHandlerA();
        Handler handlerB = new ConcreteHandlerB();

        // 设置责任链
        handlerA.setSuccessor(handlerB);

        // 发送请求
        handlerA.handleRequest("A-type request");
        handlerA.handleRequest("B-type request");
        handlerA.handleRequest("C-type request"); // 这个请求将不会被任何处理器处理
    }
}

在这个例子中,ConcreteHandlerA能够处理以"A"开头的请求,而ConcreteHandlerB能够处理以"B"开头的请求。如果请求不是以这两个字符开头,那么处理器会将其传递给它的后继者。如果没有后继者,或者后继者也无法处理该请求,那么就会输出一条"没有处理器处理该请求"的消息。

Client类的main方法中,我们创建了两个处理器对象,并将它们连接成一个责任链。然后,我们发送了几个不同类型的请求到这个责任链中。

相关推荐
晨米酱9 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
数据智能老司机14 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机15 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机15 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机15 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
使一颗心免于哀伤15 小时前
《设计模式之禅》笔记摘录 - 21.状态模式
笔记·设计模式
数据智能老司机1 天前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
数据智能老司机1 天前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
烛阴2 天前
【TS 设计模式完全指南】懒加载、缓存与权限控制:代理模式在 TypeScript 中的三大妙用
javascript·设计模式·typescript
李广坤2 天前
工厂模式
设计模式