責任鏈模式
一、什麼是責任鏈模式?
責任鏈模式(Chain Of Responsibility Pattern)爲請求創建了一個接收者對象的鏈。對請求的發送者和接收者進行解耦,這種類型的設計模式屬於行爲者模式。
責任鏈模式,通常每個接收者都包含對另一個接收者的引用。如果一個對象不能處理該請求,那麼它會把請求傳給下一個接收者,以此類推。
二、責任鏈模式的作用
讓請求發送者和接收者解耦。責任鏈上的處理者負責處理請求,客戶只需要將請求發送到責任鏈上,無需關心請求的處理細節和請求的傳遞。
JS 中的事件冒泡。JAVA WEB 中 Apache Tomcat 對 Encoding 的處理,Struts2 的攔截器,jsp servlet 的 Filter。 都使用了責任鏈模式。
三、責任鏈模式的優缺點
1、優點
- 降低耦合度,將請求的發送者和接收者解耦。
- 簡化了對象,使對象不需要知道鏈的結構。
- 增加了靈活性,可以通過改變責任鏈內的成員或次序,允許動態修改責任。
- 增加新的請求處理類很方便。
2、缺點
- 不能保證請求一定被接收。
- 系統性能將受到一定影響,而且在進行代碼調試時不太方便,可能會造成循環調用。
- 可能不容易觀察運行時的特徵,有礙於除錯。
四、責任鏈具體代碼實現
1、結構圖
2、主要角色
- Handler 處理者:定義了處理請求的接口,handler知道,下一個處理者是誰,如果自己無法處理請求,就轉給下一個處理者
- concreteHandler 具體處理者:具體的處理者是處理請求的具體角色
- 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