王海鱼 发表于 6 天前

设计模式解说02—责任链模式(Chain)

1. 概述

   界说:责任链模式是一种行为型模式,在这个模式中,通常创建了一个接收者对象的链来处理请求,该请求沿着链的次序传递。直到有对象处理该请求为止,从而到达解耦请求发送者和请求处理者的目标。

解释:责任链模式通过将多个处理器(处理对象)以链式布局连接起来,使得请求沿着这条链传递,直到有一个处理器处理该请求为止。责任链模式允许多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
⭐什么是行为型模式?
答:行为型模式主要用于形貌对类或对象怎样交互和怎样分配职责。行为型模式 (Behavioral Pattern) 是对 在不同的对象之间分别责任和算法的抽象化 。

2. 优缺点

优点:

[*]低落耦合度:请求发送者和接收者都没有对方的明确信息,而是通过抽象处理器来链接。实现了请求的发送者和处理者之间的解耦。
[*]灵活性:可以动态地增加或删除处理器,方便扩展和维护。
[*]易于实现:在责任链模式中,每个具体的处理器只必要实现自己的功能即可,不必要知道整个请求链的存在,这样更加容易实现其功能。
缺点:

[*]不能保证请求肯定会被处理:在责任链模式中,由于请求的处理是由多个对象负责的,所以不能保证请求肯定会被处理,存在由于弊端导致请求无响应的风险。
[*]性能问题:在应用责任链模式时必要控制链中的处理器数目,过多的处理器会导致处理时间增加,从而影响系统性能。
[*]调试困难:责任链模式中的处理器是动态组合的,处理逻辑较为复杂,因此必要举行详细的测试和调试。

3. 使用场景

3.1. 应用实例


[*]告假申请流程:公司内部的告假申请一般必要经过多级审批,每个审批者的职责不同,可以通过责任链模式实现申请者与处理者之间的解耦,让申请者的请求依次经过各个处理者的处理,直到终极得到审批结果。
[*]商品退换货:在线商场中,如果用户必要对商品举行退换货,涉及到订单创建、退货申请、快递配送等诸多步骤,这些步骤可以通过责任链模式实现,让每个处理者负责自己的任务,将责任链串接起来,以便完成整个退换货流程。
[*]请求处理中央:当一个请求必要经过多个处理节点举行处理时,可以采用责任链模式来组织这些处理节点,使得请求在节点之间循环传递,直到得到终极结果。比方,大型网站的访问请求处理中央,就可以采用责任链模式来处理请求。
[*]系统安全中央:当系统发生安全威胁时,可以采用责任链模式来组织安全相干的处理节点,对非常数据举行检测和拦截,保障系统安全稳定运行。

3.2. 程序场景


[*]请求的处理次序不确定:如果一个系统中存在多个处理请求的对象,且请求的处理可能必要先后次序,则可以采用责任链模式,让不同的处理对象构成责任链,依次对请求举行处理。
[*]有多个对象可必要处理请求:如果一个请求可能必要由多个对象来举行处理,而这些处理对象之间相互独立,不必要知道其他处理对象的存在,则可以采用责任链模式来实现请求的处理。
[*]必要动态安排处理流程:如果处理流程必要动态安排,可以通过动态组合责任链节点来实现。即根据实际需求,动态安排责任链的执行次序和强度。
[*]必要在不影响代码整体布局的情况下,举行功能扩展:使用责任链模式可以方便地扩展系统的功能,对业务逻辑和系统布局的初始设计基本无影响,只必要添加新的处理节点、修改处理节点间的接洽即可。

4. 布局⭐

责任链模式包含以下几个主要脚色:


[*]抽象处理器(Handler):界说一个处理请求的接口,通常包含一个处理请求的方法(如 handleRequest)和一个指向下一个处理者的引用(后继者)。
[*]具体处理器(ConcreteHandler):实现了抽象处理器接口,负责处理请求。如果能够处理该请求,则直接处理;否则,将请求传递给下一个处理者。
[*]客户端(Client):创建处理者对象,并将它们连接成一条责任链。通常,客户端只必要将请求发送给责任链的第一个处理者,无需关心请求的具体处理过程。

5. 代码实现

5.1. 需求先容

我们创建抽象类 AbstractLogger,带有详细的日记记录级别。然后我们创建三种类型的记录器,都扩展了 AbstractLogger。每个记录器判断消息的级别是否属于自己的级别,如果是则相应地打印出来,否则不打印并把消息传给下一个记录器。
https://i-blog.csdnimg.cn/direct/230a21c792bc49ba8da157e4b3c7f419.png
5.2. 代码演示


[*]创建一个抽象的记录器类(抽象处理器)
/**
* @Description 记录器类 —— 抽象处理器
* @Author gongming.Zhang
* @Date 2024/11/6 10:39
* @Version 1.0
*/
public abstract class AbstractLogger {
    public static final Integer INFO = 1;
    public static final Integer DEBUG = 2;
    public static final Integer ERROR = 3;

    // protected:对本包以及不同包的子类可见
    protected Integer level;

    // 责任链中的下一个元素
    protected AbstractLogger nextLogger;

    public void setNextLogger(AbstractLogger nextLogger) {
      this.nextLogger = nextLogger;
    }

    public void logMessage(int level, String message) {
      if (this.level <= level) {
            write(message);
      }

      // 核心逻辑,链式连接多个处理器
      if (nextLogger != null) {
            nextLogger.logMessage(level, message);
      }
    }

    // 抽象方法,具体的处理器去实现对应的逻辑
    protected abstract void write(String message);
}


[*]创建扩展了该记录器抽象类的具体实现类(具体抽象类)
/**
* @Description 控制台日志类
* @Author gongming.Zhang
* @Date 2024/11/6 10:55
* @Version 1.0
*/
public class ConsoleLogger extends AbstractLogger {

    public ConsoleLogger(int level) {
      this.level = level;
    }

    @Override
    protected void write(String message) {
      System.out.println("Standard Console::Logger: " + message);
    }
} /**
* @Description 报错日志类
* @Author gongming.Zhang
* @Date 2024/11/6 10:58
* @Version 1.0
*/
public class ErrorLogger extends AbstractLogger {

    public ErrorLogger(int level){
      this.level = level;
    }

    @Override
    protected void write(String message) {
      System.out.println("Error Console::Logger: " + message);
    }
} /**
* @Description 文件日志类
* @Author gongming.Zhang
* @Date 2024/11/6 10:58
* @Version 1.0
*/
public class FileLogger extends AbstractLogger {

   public FileLogger(int level){
      this.level = level;
   }

   @Override
   protected void write(String message) {   
      System.out.println("File::Logger: " + message);
   }
}

[*]创建不同类型的记录器,并赋予它们不同的错误级别,并在每个记录器中设置下一个记录器。(客户端)
/**
* 客户端 Client
*
* @return 返回链头
*/
private static AbstractLogger getChainOfLoggers() {
    AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
    AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
    AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);

    // 设置链路
    errorLogger.setNextLogger(fileLogger);
    fileLogger.setNextLogger(consoleLogger);

    return errorLogger;
}

/**
* 测试
*/
@Test
void testChainDesignPatterns() {
    AbstractLogger loggerChain = getChainOfLoggers();

    loggerChain.logMessage(AbstractLogger.INFO, "This is an information");
    loggerChain.logMessage(AbstractLogger.DEBUG, "This is a debug level information.");

    loggerChain.logMessage(AbstractLogger.ERROR, "This is an error information.");
}
结果:
Standard Console::Logger: This is an information.
File::Logger: This is a debug level information.
Standard Console::Logger: This is a debug level information.
Error Console::Logger: This is an error information.
File::Logger: This is an error information.
Standard Console::Logger: This is an error information.
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 设计模式解说02—责任链模式(Chain)