[01][01][12] 責任鏈模式詳解

1. 定義

使多個對象都有處理請求的機會,從而避免了請求的發送者和接收者之間的耦合關係,將這些對象串成一條鏈,並沿着這條鏈一直傳遞該請求,直到有對象處理它爲止

2. 使用場景

責任鏈模式是一種常見的模式,Struts2的核心控件FilterDispatcher是一個Servlet過濾器,該控件就是採用責任鏈模式,可以對用戶請求進行層層過濾處理,責任鏈模式在實際項目中的使用比較多,其典型的應用場景如下:

  • 一個請求需要一系列的處理工作
  • 業務流的處理,例如文件審批
  • 對系統進行擴展補充

3. 代碼實現

3.1 抽象處理器

package com.zhunongyun.toalibaba.designpatterns.responsibilitychain;

/**
 * 抽象處理器.
 */
public abstract class AbstractLogger {
    public static final int INFO = 1;    //一級日誌
    public static final int DEBUG = 2;   //二級日誌包括一級
    public static final int ERROR = 3;   //三級包括前兩個

    protected int level;

    //責任鏈下一個元素
    protected AbstractLogger nextLogger;

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

    //不同級別的記錄方法不一樣,這裏給一個抽象的記錄方法
    abstract protected void write(String message);

    //調用責任鏈處理器的記錄方法.並且判斷下一個責任鏈元素是否存在,若存在,則執行下一個方法.
    public void logMessage(int level, String message) {
        if (this.level <= level) {    //根據傳進來的日誌等級,判斷哪些責任鏈元素要去記錄
            write(message);
        }
        if (nextLogger != null) {
            nextLogger.logMessage(level, message);   //進行下一個責任鏈元素處理
        }
    }
}

3.2 具體處理器

package com.zhunongyun.toalibaba.designpatterns.responsibilitychain;

/**
 * error日誌處理器.
 */
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);
    }
}
package com.zhunongyun.toalibaba.designpatterns.responsibilitychain;

/**
 * 文件處理器.
 */
public class FileLogger extends AbstractLogger {
    public FileLogger(int level) {
        this.level = level;
    }

    @Override
    protected void write(String message) {
        System.out.println("File Console::Logger"+message);
    }
}
package com.zhunongyun.toalibaba.designpatterns.responsibilitychain;

/**
 * 控制檯處理器.
 */
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);
    }
}

3.3 責任鏈

package com.zhunongyun.toalibaba.designpatterns.responsibilitychain;

/**
 * 處理鏈
 */
public class ChainPatternDemo {

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

3.4 測試類

package com.zhunongyun.toalibaba.designpatterns.responsibilitychain;

public class Test {
    public static void main(String[] args) {
        AbstractLogger logger = ChainPatternDemo.getChainOfLoggers();
        logger.logMessage(1,"一級日誌記錄");
        System.out.println("--------------------------------");
        logger.logMessage(2,"二級日誌記錄");
        System.out.println("--------------------------------");
        logger.logMessage(3,"三級日誌記錄");
    }
}

4. 優缺點

4.1 優點

  • 責任鏈模式將請求和處理分開,請求者不知道是誰處理的,處理者可以不用知道請求的全貌
  • 提高系統的靈活性

4.2 缺點

  • 降低程序的性能,每個請求都是從鏈頭遍歷到鏈尾,當鏈比較長的時候,性能會大幅下降
  • 不易於調試,由於該模式採用了類似遞歸的方式,調試的時候邏輯比較複雜
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章