責任鏈模式(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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章