设计模式-行为型设计模式-责任链模式

19 阅读2分钟

责任链模式定义

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

意图

避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

代码实例

java 具有六大日志级别,分别是fatal 6 --> error 5 --> warn 4 --> info 3 --> debug 2 --> trace 1

定义异常枚举类,枚举类通过有参构造器设置了日志级别以及对应的日志描述

@Getter
@AllArgsConstructor
public enum LoggerEnum {

    TRACE(1, "程序执行轨迹信息"),
    DEBUG(2, "调试信息"),
    INFO(3, "程序执行轨迹信息"),
    WARN(4, "警告信息"),
    ERROR(5, "错误信息"),
    FATAL(6, "重大错误");
    Integer level;

    String desc;
}

定义抽象日志类,组合了日志枚举类,具有指向自身的对象,由于多态特性,会指向扩展的子类。打印级别小的信息。

public abstract class AbstractLogger {

    protected LoggerEnum loggerEnum;

    private AbstractLogger nextLogger;

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

    public void logMessage(LoggerEnum loggerEnum, String message){
        if(this.loggerEnum.level <= loggerEnum.level){
            write(message);
        }
        if(nextLogger !=null){
            nextLogger.logMessage(loggerEnum, message);
        }
    }

    abstract public void write(String message);

}

定义扩展的子类,分别是6打日志级别

trace:用于展现程序执行的轨迹

public class TraceLogger extends AbstractLogger{

    public TraceLogger(LoggerEnum loggerEnum) {
        this.loggerEnum = loggerEnum;
    }

    @Override
    public void write(String message) {
        System.out.println("TraceLogger[Trace]===>"+message);
    }
}

info:用于协助低层次的调试

public class InfoLogger extends AbstractLogger {

    public InfoLogger(LoggerEnum loggerEnum) {
        this.loggerEnum = loggerEnum;
    }

    @Override
    public void write(String message) {
        System.out.println("InfoLogger[INFO]===>"+message);
    }
}

debug:用于基本高层次的诊断信息,在长时间运行的代码段开始运行及结束运行时应该产生消息,以便知道现在系统在干什么。

public class DebugLogger extends AbstractLogger{

    public DebugLogger(LoggerEnum loggerEnum) {
        this.loggerEnum = loggerEnum;
    }

    @Override
    public void write(String message) {
        System.out.println("DebugLogger[DEBUG]===>"+message);
    }
}

warn:不一定是一个bug,但是想知道这种警告

public class WarnLogger extends AbstractLogger{

    public WarnLogger(LoggerEnum loggerEnum) {
        this.loggerEnum = loggerEnum;
    }

    @Override
    public void write(String message) {
        System.out.println("WarningLogger[Warning]===>"+message);
    }
}

error:显示一个错误,但不至于将系统挂起

public class ErrorLogger extends AbstractLogger {

    public ErrorLogger(LoggerEnum loggerEnum) {
        this.loggerEnum = loggerEnum;
    }

    @Override
    public void write(String message) {
        System.out.println("ErrorLogger[ERROR]===>"+message);
    }
}

fatal:某个严重的错误事件将会导致应用程序的退出

public class FatalLogger extends AbstractLogger{

    public FatalLogger(LoggerEnum loggerEnum) {
        this.loggerEnum = loggerEnum;
    }

    @Override
    public void write(String message) {
        System.out.println("FatalLogger[Fatal]===>"+message);
    }
}

其中 log4j 具备 8 个日志级别,添加了最低的日志级别 ALL 最低等级的,用于打开所有日志记录。最高的日志级别 OFF 最高等级的日志,关闭所有日志。

获取日志责任链的工厂,设置了链式的指向关系,返回最高级别的,在调用这个方法时,回去匹配当前节点日志的信息,打印日志链指向的后续的日志节点。

public class LoggerChainFactory {

    public AbstractLogger getChainOfLoggers() {
        AbstractLogger fatalLogger = new FatalLogger(LoggerEnum.FATAL);
        AbstractLogger errorLogger = new ErrorLogger(LoggerEnum.ERROR);
        AbstractLogger warnLogger = new WarnLogger(LoggerEnum.WARN);
        AbstractLogger debugLogger = new DebugLogger(LoggerEnum.DEBUG);
        AbstractLogger infoLogger = new InfoLogger(LoggerEnum.INFO);
        AbstractLogger traceLogger = new TraceLogger(LoggerEnum.TRACE);

        fatalLogger.setNextLogger(errorLogger);
        errorLogger.setNextLogger(warnLogger);
        warnLogger.setNextLogger(debugLogger);
        debugLogger.setNextLogger(infoLogger);
        infoLogger.setNextLogger(traceLogger);

        return fatalLogger;
    }
}

责任链模式调用的客户端

public class ChainClient {
    public static void main(String[] args) {
        AbstractLogger abstractLogger = new LoggerChainFactory().getChainOfLoggers();

        abstractLogger.logMessage(LoggerEnum.INFO,"standard");
        System.out.println("=======================================");
        abstractLogger.logMessage(LoggerEnum.FATAL,"fatal");

    }
}

效果

image.png