設計模式-責任鏈模式-日誌分級打印示例

責任鏈模式

責任鏈模式-行爲型模式
意圖:避免請求發送者和接受者耦合在一起,讓多個對象都有可能接受請求,將這些對象連接成一條鏈,並且沿着這條鏈傳遞請求,知道有對象處理它爲止。
關鍵代碼:攔截的類都實現統一接口,Handler 裏面聚合它自己,在 HandlerRequest 裏判斷是否合適,如果沒達到條件則向下傳遞,向誰傳遞之前 set 進去。
應用實例:三國殺中有人使用錦囊時,系統提示其他用戶是否使用無懈可擊,運用的就是責任鏈模式
使用場景: 1、有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定。 2、在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。 3、可動態指定一組對象處理請求。
參考鏈接:https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html

代碼分析(先看代碼示例)

  1. 實例代碼中表示的是日誌打印功能,通過責任鏈模式將不同級別的日誌信息通過不同的方式打印出來。
  2. AbstractLogger類作爲抽象的接受者類,就是上文提到的Handler類,ChainPatternDemo作爲發送者(其實描述的不準確,具體應該說發送者其實就是其中的一句代碼,這個實例中沒有明確的發送者對象。接受者類中比較重要的方法就是setNextLogger(),通過這個方法確定了後續中責任鏈的順序,有點像鏈表,而logMessage()方法作爲這個判斷接受對象以及對收到的請求做的處理,就是上文中提到的HandlerRequest。
  3. 總體來說,代碼思路比較明確,通過實現接受者接口,創建幾種可以處理請求的Handler類,每個Handler類至少包含兩個方法一個setNextLogger()[爲了與其他handler對象構成責任鏈],一個HandlerRequest()[對可接受對象或請求做的合法操作]。
  4. UML 類圖如下:
    責任鏈模式

代碼示例

//步驟1、創建抽象的接受者類,這裏是記錄器類
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); // 轉向下一個記錄器的logMessage()方法
        }
    }

    abstract protected void write(String message);

}
//步驟2、創建擴展該記錄器類的實體類
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);
    }
}

//步驟3、創建不同類型的記錄器,賦予他們不同的錯誤級別,並在每個記錄器中設置下一個記錄器.每一個記錄器中下一個記錄器代表的是鏈的一部分.
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.");
    }
}

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