Wzorzec projektowy Łańcuch Odpowiedzialności

Wzorzec projektowy Łańcuch Odpowiedzialności pozwala na przekazywanie odpowiedzialności do następnych obsługujących.

Przykład na podstawie loggerów

Załóżmy, że chcemy stworzyć bibliotekę umożliwiającą logowanie (coś w stylu log4j). Biblioteka ta ma umożliwiać logowanie do różnych ujść (do konsoli, do pliku…). Spójrzmy jak można by wykorzystać tutaj wzorzec Łańcuch Odpowiedzialności:

interface Logger {
    void log(String text);
}

class FileLogger implements Logger {
    Logger successor;

    FileLogger(){}

    FileLogger(Logger successor){
       this.successor = successor;
    }

    public void log(String text) {
        //saving logs to a file
        if(this.successor != null)
            this.successor.log(text, level);
    }

}

class ConsoleLogger implements Logger {
    Logger successor;

    ConsoleLogger(){}

    ConsoleLogger(Logger successor){
       this.successor = successor;
    }

    public void log(String text, String level) {
        //logging to console
        if(this.successor != null)
            this.successor.log(text, level);
    }

}

każda klasa logowania obsługuje logowanie i przekazuje ten sam tekst do zalogowania do następnego elementu łańcucha (jeśli takowy jest). Kod klienta mógłby wyglądać następująco:

FileLogger fileLogger = new FileLogger();
ConsoleLogger consoleLogger = new ConsoleLogger(fileLogger);

consoleLogger.log("Some text");

jest to dosyć prymitywna implementacja, ale pokazująca ideę wzorca. W bardziej wyrafinowanych przypadkach łańcuch może być przerwany w zależności od warunków – przykładowo dla łańcucha walidacyjnego jeśli jeden z elementów stwierdzi, że walidacja się nie powiodła, to w większości zastosowań nie powinien przekazywać obsługi dalej. Inną kwestią jest to, że w tym przypadku nasz łańcuch ma nazwę consoleLogger co by mogło świadczyć, że logowanie się odbędzie tylko do konsoli (można to rozwiązać opakowując cały łańcuch dodatkową klasą).

Pozostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *