责任链模式(Chain Of Responsibility Pattern)

责任链模式

一、什么是责任链模式?

  责任链模式(Chain Of Responsibility Pattern)为请求创建了一个接收者对象的链。对请求的发送者和接收者进行解耦,这种类型的设计模式属于行为者模式。
  责任链模式,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把请求传给下一个接收者,以此类推。

二、责任链模式的作用

  让请求发送者和接收者解耦。责任链上的处理者负责处理请求,客户只需要将请求发送到责任链上,无需关心请求的处理细节和请求的传递。
  JS 中的事件冒泡。JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,jsp servlet 的 Filter。 都使用了责任链模式。

三、责任链模式的优缺点

1、优点
  1. 降低耦合度,将请求的发送者和接收者解耦。
  2. 简化了对象,使对象不需要知道链的结构。
  3. 增加了灵活性,可以通过改变责任链内的成员或次序,允许动态修改责任。
  4. 增加新的请求处理类很方便。
2、缺点
  1. 不能保证请求一定被接收。
  2. 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
  3. 可能不容易观察运行时的特征,有碍于除错。

四、责任链具体代码实现

1、结构图
2、主要角色
  1. Handler 处理者:定义了处理请求的接口,handler知道,下一个处理者是谁,如果自己无法处理请求,就转给下一个处理者
  2. concreteHandler 具体处理者:具体的处理者是处理请求的具体角色
  3. Client 请求客户:请求者角色,就是向第一个具体的handler发送请求的角色,并连接好责任链
3、具体java代码

Handler 处理:

package com.designpattern.chainOfResponsibilityPattern;

/**
 * 抽象日志类
 * Handler 处理者
 * 定义了处理请求的接口,handler知道,下一个处理者是谁,如果自己无法处理请求,就转给下一个处理者。
 *
 * @author zhongtao on 2018/10/23
 */
public abstract class AbstractLogger {
    public static int INFO = 1;
    public static int DEBUG = 2;
    public static int ERROR = 3;

    private int level;

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

    private AbstractLogger nextLogger;

    /**
     * 指定下一个处理者
     *
     * @param nextLogger
     */
    public void setNextLogger(AbstractLogger nextLogger) {
        this.nextLogger = nextLogger;
    }

    abstract public void write(String message);

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

具体处理者:

/**
 * 扩展了该记录器类的实体类
 * 具体责任处理者
 * @author zhongtao on 2018/10/23
 */
public class ConsoleLogger extends AbstractLogger {
    public ConsoleLogger(int level) {
        super(level);
    }

    @Override
    public void write(String message) {
        System.out.println("Standard Console: logger->" + message);
    }
}

public class FileLogger extends AbstractLogger {
    public FileLogger(int level) {
        super(level);
    }

    @Override
    public void write(String message) {
        System.out.println("File : logger->" + message);
    }
}

public class ErrorLogger extends AbstractLogger {
    public ErrorLogger(int level) {
        super(level);
    }

    @Override
    public void write(String message) {
        System.out.println("Error Console: logger->" + message);
    }
}

创建责任链:

package com.designpattern.chainOfResponsibilityPattern;

/**
 * 创建责任链
 *
 * @author zhongtao on 2018/10/23
 */
public class ChainDemo {

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

测试责任链模式:

package com.designpattern.chainOfResponsibilityPattern;

import org.junit.Test;

/**
 * 测试责任链模式
 *
 * @author zhongtao on 2018/10/23
 */
public class ChainPatternTest {
    
    @Test
    public void testChainPattern() {
        AbstractLogger loggerChain = ChainDemo.getChainOfLoggers();

        loggerChain.logMessage(AbstractLogger.INFO, "This is an information");
        System.out.println();
        loggerChain.logMessage(AbstractLogger.DEBUG, "This is an debug level information");
        System.out.println();
        loggerChain.logMessage(AbstractLogger.ERROR, "This is an error information");
    }
}

测试结果:

Standard Console: logger->This is an information

File : logger->This is an debug level information

Error Console: logger->This is an error information

源码地址:https://github.com/zt19994/designPattern

原文地址:https://www.cnblogs.com/zt19994/p/9843363.html