責任鏈模式
責任鏈模式
-行爲型模式
意圖
:避免請求發送者和接受者耦合在一起,讓多個對象都有可能接受請求,將這些對象連接成一條鏈,並且沿着這條鏈傳遞請求,知道有對象處理它爲止。
關鍵代碼
:攔截的類都實現統一接口,Handler 裏面聚合它自己,在 HandlerRequest 裏判斷是否合適,如果沒達到條件則向下傳遞,向誰傳遞之前 set 進去。
應用實例
:三國殺中有人使用錦囊時,系統提示其他用戶是否使用無懈可擊,運用的就是責任鏈模式
使用場景
: 1、有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定。 2、在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。 3、可動態指定一組對象處理請求。
參考鏈接
:https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html
代碼分析(先看代碼示例)
- 實例代碼中表示的是日誌打印功能,通過責任鏈模式將不同級別的日誌信息通過不同的方式打印出來。
- AbstractLogger類作爲抽象的接受者類,就是上文提到的Handler類,ChainPatternDemo作爲發送者(其實描述的不準確,具體應該說發送者其實就是其中的一句代碼,這個實例中沒有明確的發送者對象。接受者類中比較重要的方法就是setNextLogger(),通過這個方法確定了後續中責任鏈的順序,有點像鏈表,而logMessage()方法作爲這個判斷接受對象以及對收到的請求做的處理,就是上文中提到的HandlerRequest。
- 總體來說,代碼思路比較明確,通過實現接受者接口,創建幾種可以處理請求的Handler類,每個Handler類至少包含兩個方法一個setNextLogger()[爲了與其他handler對象構成責任鏈],一個HandlerRequest()[對可接受對象或請求做的合法操作]。
- UML 類圖如下:
代碼示例
abstract class AbstractLogger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
protected AbstractLogger nextLogger;
public void setNextLogger(AbstractLogger nextLogger){
this.nextLogger = nextLogger;
}
public void logMessage(int level, String message){
if(this.level <= level){
write(message);
}
if(nextLogger !=null){
nextLogger.logMessage(level, message);
}
}
abstract protected void write(String message);
}
class ConsoleLogger extends AbstractLogger {
public ConsoleLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Standard Console::Logger: " + message);
}
}
class ErrorLogger extends AbstractLogger {
public ErrorLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error Console::Logger: " + message);
}
}
class FileLogger extends AbstractLogger {
public FileLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("File::Logger: " + message);
}
}
public class ChainPatternDemo {
private 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;
}
public static void main(String[] args) {
AbstractLogger loggerChain = getChainOfLoggers();
loggerChain.logMessage(AbstractLogger.INFO, "This is an information.");
loggerChain.logMessage(AbstractLogger.DEBUG,
"This is a debug level information.");
loggerChain.logMessage(AbstractLogger.ERROR,
"This is an error information.");
}
}