Łańcuch zobowiązań (ang. Chain of responsibility) (wzorzec behawioralny) zwany także Łańcuchem odpowiedzialności umożliwia przetwarzanie żądania przez łańcuch różnych obiektów. Łańcuch oparty jest o strukturę listy jednokierunkowej, tzn. obiekty mają ustaloną kolejność i znają swojego następnika. Klient zleca wykonanie operacji pierwszemu elementowi łańcucha, a gdy ten nie jest w stanie lub nie jest uprawniony do zakończenia żądania to przekazuje odpowiedzialność jego realizacji swojemu następnikowi. Jeśli następnik nie może podjąć działania wówczas również przekazuje je kolejnemu elementowi. Przetwarzanie i przekazywanie zadania działa rekurencyjnie dla każdego obiektu w łańcuchu. Elementy łańcucha analizują zadania i zapewniają jego obsługę lub przekazują zadanie dalej. Dzięki temu struktura łańcucha jest otwarta na modyfikacje, może być dynamicznie zmieniana, a także zmniejsza się liczba zależności klientem, a potencjalnymi odbiorcami.
Ograniczenia
Klient nie zna ostatecznego wykonawcy. Co więcej Łańcuch zobowiązań nie gwarantuje obsługi zleconego zadania. Ponadto w zależności od implementacji, żądanie może być częściowo obsługiwane przez różne elementy. Debugowanie staje się zatem utrudnione, a wydajność maleje.
Użycie
Wzorzec używany jest w mechanizmach przetwarzania podobnych żądań, dla których proces klasyfikacji powinien przebiegać w ustalonym porządku. Klient nie musi znać dokładnego wykonawcy oraz szczegółów implementacji dzięki czemu wykorzystywany jest w sytuacjach dynamicznie zmieniających się wymagań.
Implementacja
Abstrakcyjna klasa Handler definiuje szablon metody przepływu obsługi żądania, natomiast klasy ją rozszerzające Handler1, Handler2 itd dostarczają szczegółów implementacji zadania.
Poniższy listing przedstawia implementację Łańcucha zobowiązań dla żądania Request i wykonawców typu Handler.
Klient tworzy Łańcuch zobowiązań i zleca obsługę żądania.
Przykład
Kantor wymiany walut wykorzystuje aplikację Exchanger do optymalizacji wydawanych nominałów w przeprowadzanych transakcjach. Kasjer otrzymuje zapytanie od klienta, a następnie definiuje zasady wydawanych nominałów. Na podstawie zleconej transakcji i zasad przeprowadzana jest symulacja, która w rezultacie podaje informacje o nominałach, które należy wypłacić klientowi. Do realizacji tego zadania wykorzystany został wzorzec Łańcuch zobowiązań do prezentuje poniższy listing.
Kasjer na podstawie zaleceń oraz stanu depozytu definiuje priorytety wydawanych nominałów. Wprowadza zlecenie klienta do systemu i dokonuje symulacji.
Biblioteki
Metoda log klasy Logger standardowej biblioteki Java wykorzystuje wzorzec Łańcuch zobowiązań.