Java特性之设计模式【责任链模式】

一、责任链模式

概述

顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推

主要解决

职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了

何时使用

  • 在处理消息的时候以过滤很多道

优缺点

优点:

  • 降低耦合度。它将请求的发送者和接收者解耦
  • 简化了对象。使得对象不需要知道链的结构
  • 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任
  • 增加新的请求处理类很方便

缺点:

  • 不能保证请求一定被接收
  • 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用
  • 可能不容易观察运行时的特征,有碍于除错

1. 各个角色介绍

1.1 抽象处理者(Handler)

  • 定义一个处理请求的接口,通常包含一个处理请求的方法(如 handleRequest)和一个指向下一个处理者的引用(后继者)

1.2 具体处理者(ConcreteHandler)

  • 实现了抽象处理者接口,负责处理请求。如果能够处理该请求,则直接处理;否则,将请求传递给下一个处理者

2. UML图

​ 我们创建抽象类 AbstractLogger,带有详细的日志记录级别。然后我们创建三种类型的记录器,都扩展了 AbstractLogger。每个记录器消息的级别是否属于自己的级别,如果是则相应地打印出来,否则将不打印并把消息传给下一个记录器

在这里插入图片描述

3. 具体例子和代码

角色分配

  • AbstractLogger:抽象日志器

    • ConsoleLogger:控制面板日志器
    • ErrorLogger:错误日志器
    • FileLogger:文件日志器

3.1 抽象日志器及其子类

  • AbstractLogger
package com.vinjcent.prototype.responsibility;

/**
 * @author vinjcent
 * @description 抽象日志器
 * @since 2024/4/1 10:13
 */
public abstract class AbstractLogger {

    public static int INFO = 1;
    public static int DEBUG = 2;
    public static int ERROR = 3;

    protected int level;


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

    /**
     * 设置下一个日志器
     *
     * @param nextLogger 下一个日志器
     */
    public void setNextLogger(AbstractLogger nextLogger) {
        this.nextLogger = nextLogger;
    }

    /**
     * 执行日志
     *
     * @param level   日志等级
     * @param message 日志信息
     */
    public void logMessage(int level, String message) {
        if (this.level <= level) {
            write(message);
        }
        if (nextLogger != null) {
            nextLogger.logMessage(level, message);
        }
    }

    /**
     * 写日志
     *
     * @param message 日志内容
     */
    abstract protected void write(String message);


}

  • ConsoleLogger
package com.vinjcent.prototype.responsibility;

/**
 * @author vinjcent
 * @description 控制面板日志器
 * @since 2024/4/1 10:19
 */
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);
    }

}

  • ErrorLogger
package com.vinjcent.prototype.responsibility;

/**
 * @author vinjcent
 * @description 错误日志器
 * @since 2024/4/1 10:26
 */
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);
    }

}

  • FileLogger
package com.vinjcent.prototype.responsibility;

/**
 * @author vinjcent
 * @description 文件日志器
 * @since 2024/4/1 10:21
 */
public class FileLogger extends AbstractLogger {

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

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

}

3.2 测试主函数

package com.vinjcent.prototype.responsibility;

/**
 * @author vinjcent
 * @description 责任链模式
 * @since 2024/4/1 10:25
 */
public class Main {

    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;
    }

    public static void main(String[] args) {
        AbstractLogger loggerChain = getChainOfLoggers();

        // INFO < DEBUG < ERROR
        loggerChain.logMessage(AbstractLogger.INFO,
                "This is an information.");
        System.out.println("INFO 级别结束...");

        loggerChain.logMessage(AbstractLogger.DEBUG,
                "This is a debug level information.");
        System.out.println("DEBUG 级别结束...");

        loggerChain.logMessage(AbstractLogger.ERROR,
                "This is an error information.");
        System.out.println("ERROR 级别结束...");

        System.out.println("------");

    }

}

  • 测试结果

在这里插入图片描述

4. 使用场景

  • 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定
  • 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求
  • 可动态指定一组对象处理请求

在这里插入图片描述

  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Naijia_OvO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值