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 缺點
- 降低程序的性能,每個請求都是從鏈頭遍歷到鏈尾,當鏈比較長的時候,性能會大幅下降
- 不易於調試,由於該模式採用了類似遞歸的方式,調試的時候邏輯比較複雜