Skip to content

Witaj w Świecie Jutra!

  • Technologie jutra
  • Sprzęt jutra
  • Aplikacje jutra
  • Programowanie
  • Księga Drogi
  • Renowacja
  • Różności
  • Archiwum
  • Autor
  • Home
  • Wszystko
  • Wzorce projektowe – Chain of Responsibility
  • Programowanie
  • Wszystko

Wzorce projektowe – Chain of Responsibility

Jakub Raczkowski 2 lutego 2024

Źródło obrazka: Pixels.com (aut. Hans Jankowski)

Bohater dzisiejszego wpisu z jednej strony potrafi wyglądem przypominać Dekoratora. Z drugiej jego zachowaniu bliżej do wzorca Stan. Poznajcie: Łańcuch odpowiedzialności!

Wyobraźmy sobie mały bar w którym można się najeść i napić. Siedzi tam sobie klient i popija kapuczynę przeglądając telefon. W pewnej chwili próbując chwycić za filiżankę omyłkowo ją potrącił i wylał napój. Zauważył to sprzedawca i ruszył na miejsce z mopem.

Ale to nie wszystko. Klient zaczyna się awanturować, że utrata kawy to nie jego wina, że kubek był mokry i mu się wyślizgnął. Żąda nowej kapuczyny, a po odmowie ze strony sprzedawcy mówi, że chce się widzieć z kierownikiem.

Przychodzi wezwany kierownik i zaczyna się wymiana zdań. Klient krzyczy, a menedżer próbuje go uspokoić. W pewnym momencie dochodzi do gróźb, zaczyna się szamotanina. W tym miejscu do gry wchodzi policjant po służbie, który do tej pory tylko obserwował sytuację znad swojej herbaty.

Źródło: film Pulp Fiction

Przytoczona historia obrazuje w jaki dokładnie sposób działa i kiedy się przydaje wzorzec Łańcuch. Domyślnie łączy on klasy z tym samym interfejsem i przepuszcza obiekt klienta przez ich kolejne metody. Czasami już pierwsza załatwi potrzebę obiektu, a czasem dopiero ta ostatnia (albo żadna).

Jeśli problemem byłaby tylko plama na podłodze, to wystarczył by sam sprzedawca z mopem, ale kiedy pojawiły się groźby i przemoc, potrzebna była policja.

Gdyby zależało wam na przykładach bardziej związanych z programowaniem mógłbym wymienić filtr antyspamowy na kontach mailowych. Kiedy przychodzi nowa poczta, najpierw sprawdza się czy to nie spam. Potem sprawdza się czy nadawca nie jest zapisany w naszych kontaktach – jeśli tak to mail leci do folderu Ważne. I tak dalej.

Nie każdy spam jest zły.

We wstępniaku mówiłem, że składnia Łańcucha wygląda trochę jak ta z Dekoratora, spójrzcie sami:

Mail mail = new Mail(); 
mail.setFilter(new SpamFilter(new RegularMail(new ImportantMail(null))));

Poczta przechodzi przez Spam, potem przez Zwykłe Wiadomości, potem przez Ważne. Na każdym z tych filtrów może się zatrzymać. Spójrzmy jaka jest oficjalna definicja Łańcucha:

Łańcuch odpowiedzialności – umożliwia dynamiczne dodawanie i usuwanie procedur obsługi poprzez zmianę elementów lub kolejności łańcucha. Ponadto upraszcza obiekt, ponieważ nie wymaga utrzymywania informacji o strukturze łańcucha – separuje nadawcę żądania od jego odbiorców.

Rusz głową! Wzorce projektowe

Jeśli zaś chodzi o strukturę to ważne aby każde z ogniw Łańcucha posiadało informację o jego następcy – do kogo się zwrócić jeśli samemu nie uda się sprostać potrzebom obiektu. Wyglądem kodu przypomina to nieco wzorzec Stan i jego odniesienia do kolejnych stanów. Pamiętajmy jednak, że „stany” to hermetyzowane zachowania jednego obiektu, natomiast w Łańcuchu mamy metody różnych klas przez które ma przejść obiekt (albo się na którejś zatrzymać).

Ale po kolei…

To co lubię w grach cRPG to uczucie zagubienia i swojej maleńkości wobec wrogów na początku rozgrywki. Potem poznajemy ten świat, zdobywamy doświadczenie i podchodzimy do coraz to trudniejszych wyzwań. Jeśli nie zaniedbaliśmy rozwoju, to do końcowego bossa wkraczamy bez jakiejkolwiek spiny i tylko jak już jest po wszystkim przypominamy sobie o całej torbie mikstur siły, niewrażliwości i szybkości jakie chomikowaliśmy na czarną godzinę, która nigdy nie nadeszła.

Równocześnie nienawidzę, kiedy gra wymusza skalowanie przeciwników do naszego poziomu. Niby, że dla balansu rozgrywki, ale chrzanię taką sytuację, kiedy zwykły szczur nagle ma 200 punktów życia, tylko dlatego bo podekspiliśmy. Już wolę żeby było jak w Gothicu – w czasie wypełniania ostatnich questów biegałem przez mapę jak szalony i tylko od niechcenia rozpłatywałem ścigające mnie Zębacze – potwory, które brały mnie na hita przez pierwsze godziny zabawy.

Zębacz (Gothic 1)

W takich realiach naturalnym jest, że czasami zawędrujemy za daleko i natrafimy na przeciwnika, który położy nas jednym machnięciem łapy. Wtedy korzystamy z metody loadGame() i już wiemy z kim nie należy zadzierać… póki nie podniesiemy poziomu i nie kupimy lepszego miecza.

Na bazie powyższego stworzyłem kawałek kodu (tutaj), który pokazuje jak owa sytuacja wyglądałaby ze wzorcem Łańcuch:

Tym razem postawiliśmy na brutalną siłę barbarzyńcy.

Widzimy, że nasz barbarzyńca z pierwszym poziomie nie stanowi wyzwania nawet dla Goblina, ale z kolejnymi levelami udaje mu się pokonywać coraz to mocniejszych wrogów, aż na placu boju pozostał tylko on. Zwycięstwo!

public void defend(Barbarian barbarian) {
            if (barbarian.level <= 3) System.out.println("Goblin: Dam mu radę sam!");
            else {
                System.out.println("Goblin: Potrzebuję pomocy!");
                barbarian.setEnemy(nextEnemy);
            }
        }

Powyżej widzimy metodę Goblina, która sprawdza czy samemu da radę obiektowi barbarzyńcy, a jeśli nie to wysyła go do nextEnemy wstrzykniętego wcześniej do swojego konstruktora.

Tak wygląda to w dynamicznej implementacji, kiedy kolejne ogniwa wybierane są w czasie tworzenia łańcucha:

Barbarian barbarianLv1 = new Barbarian(1);
        barbarianLv1.setEnemy(new Goblin(new OrcWarlord(new TrollKing(null))));

Możemy też nieco usztywnić architekturę, tak jak to zrobiłem w drugiej, rozbudowanej wersji kodu (tutaj). Wtedy następny przeciwnik jest już na stałe ustawiony u poprzednika:

Heros na pierwszym poziomie położył Goblina, ale nie dał rady Orkowi.
Na 4 levelu dochodzi skill ofensywny „Atak z wyskoku” dzięki któremu bohaterowi udało się dostać do bossa.
Na 7 levelu mamy kolejną umiejętność: 'Unik’ – tylko dzięki temu udało się pokonać Króla Trolli.

ITCandidateEvaluator

Bez skruchy przyznaję, że wzorzec Chain of Responsibility wybrałem do opisania właśnie dlatego bo miałem fajny pomysł na jego zakodowanie z udziałem Króla Trolli i jego przydupasów. Pisanie tego o ósmej rano, ze stygnącą kawą obok monitora dało mi sporo frajdy – nawet kiedy Chat GPT ocenił to na słabą próbę podejścia do wzorca (dlatego powstała jeszcze krótsza, bardziej „książkowa” wersja kodu).

Mimo osobistej sympatii do Łańcucha nie widzę jednak wiele możliwości umieszczenia go u siebie w kolejnym projekcie. Niby genialnie nadałby się do logowania wyjątków o różnych poziomach ważności, ale po co będę sam to pisał, skoro logger log4j zrobi to za mnie?

Tyle w temacie wzorców prostych. W kolejnym odcinku przerobimy jeszcze Model-View-Controller i chwilowo dajemy sobie na wstrzymanie z tą serią.

Tags: design patterns programming

Continue Reading

Previous: Wzorce projektowe – Builder
Next: Wzorce projektowe – MVC

Related Stories

Mageege Moon104 – test niskoprofilowego mechanika
  • Sprzęt

Mageege Moon104 – test niskoprofilowego mechanika

11 marca 2025
Przebranżowienie cz.4
  • Programowanie

Przebranżowienie cz.4

27 lutego 2025
Smartfon Jutra
  • Sprzęt

Smartfon Jutra

15 lutego 2025

Ze świata

  • Antyweb
  • Kwantowo
  • Dwóch po dwóch
Nowy iPhone rozładowywał się przez noc. Skuteczna okazała się tylko jedna procedura
To jeden z największych problemów na polu walki. Firma z USA wie, jak go rozwiązać
Zostawiasz ładowarkę w gniazdku? Sprawdź, ile prądu naprawdę zużywa
Nie działa Ci ChatGPT? W usługę trafiła poważna awaria
Xbox szuka sposobu na odbicie się od dna. Lekarstwem ma być ostatnia decyzja
Google Pixel 11a już bez tajemnic. Kilka kluczowych zmian
Garmin wydłuża czas pracy zegarków. Tę aktualizację warto pobrać
LEGO przygotowało prawdziwą ucztę dla kolekcjonerów. Ten zestaw zachwyca od pierwszego spojrzenia
Sony wyciska użytkowników PlayStation od lat. Dziw, że dopiero teraz zauważyliście
YouTube rozczarowuje użytkowników. Wszystkiemu winien nowy błąd
Śpisz z telefonem przy poduszce? Lepiej odłóż go w inne miejsce
Stworzył fizyczne wydania gier na Steama. Są dostępne na "kartridżach"
Złoto na strychu? Te stare telefony mogą być dziś warte fortunę
Thule EnRoute 12L – recenzja. Wypełnia lukę między nerką, a plecakiem podróżnym
HP blokuje nawet oryginalne tusze? Kontrowersje wokół aktualizacji drukarek narastają
"Polski ChatGPT" goni najlepszych. Jest świetny, ale ja nie kupuję w nim jednej rzeczy
Chcesz jeść mniej? Lepiej tak nie rób. Naukowcy obalili popularny mit
Spotify nadrabia zaległości. Potrzebna opcja trafi do aplikacji
Ta platforma VOD kpi sobie z Polaków. Nie tak to miało wyglądać
Garmin CIRQA na pierwszym zdjęciu. Premiera tuż za rogiem
SpudCell – syntetyczna komórka, która udaje życie
Mega upał, omega manipulacja
Coraz więcej dowodów, coraz mniej pewności
Matematyczno-restauracyjny dylemat Ryszarda
Silnik produkujący informacje zamiast spalin
Orzeczenie w sprawie En Arche v. Adam Adamczyk
To by było na tyle, jeśli chodzi o możliwość ugody z kreacjonistami
Ocalić od zapomnienia
Ostatni kwant
ALH 84001 – meteoryt, o którym mówiono nawet w Białym Domu
Tańszy Game Pass, droższy Steam Deck i Internet 0202122 – Odcinek #135
Elite Dangerous. Gra, z której odchodzi się po cichu
Gry zasługujące na adaptację filmową – Odcinek #134
Relacja z RePlay Fest 2026
Najlepsze intra i openingi w grach – Odcinek #133
AI, Star Trek, Rycerz Siedmiu Królestw, Festiwal dem na Steam Next Fest – Odcinek #132
Gry, filmy i seriale w 2025 i 2026 roku – Odcinek #131
30 lat konsoli PlayStation – Odcinek #130
Omawiamy serię The Walking Dead (gość: Stary Gracz)
Nikt nie potrzebuje cienkich smartfonów – Odcinek #129

To może cię zainteresować:

Mageege Moon104 – test niskoprofilowego mechanika
  • Sprzęt

Mageege Moon104 – test niskoprofilowego mechanika

11 marca 2025
Przebranżowienie cz.4
  • Programowanie

Przebranżowienie cz.4

27 lutego 2025
Smartfon Jutra
  • Sprzęt

Smartfon Jutra

15 lutego 2025
Czym jest Swagger?
  • Programowanie

Czym jest Swagger?

22 lipca 2024
  • Technologie jutra
  • Sprzęt jutra
  • Aplikacje jutra
  • Programowanie
  • Księga Drogi
  • Renowacja
  • Różności
  • Archiwum
  • Autor
Copyright © All rights reserved. | DarkNews by AF themes.