všetky vzory

Chain of Responsibility

Posúva požiadavku po reťazi spracovateľov, kým ju niekto nevyrieši.

class Spracovatel {  constructor() {    this.dalsi = null;  }   posli(ziadost) {    if (this.zvladne(ziadost)) {      this.vybav(ziadost);      return;    }    if (this.dalsi !== null) {      this.dalsi.posli(ziadost);    }  }} class Veduci extends Spracovatel {  zvladne(ziadost) {    return ziadost.suma <= 1000;  }} class Riaditel extends Spracovatel {  zvladne(ziadost) {    return ziadost.suma <= 10000;  }} class Predstavenstvo extends Spracovatel {  zvladne(ziadost) {    return true;  }} const veduci = new Veduci();veduci.dalsi = new Riaditel();veduci.dalsi.dalsi = new Predstavenstvo(); veduci.posli({ suma: 500 });veduci.posli({ suma: 8000 });veduci.posli({ suma: 200000 });

Celý priebeh v texte (12 krokov)
  1. Spracovatel je abstraktný a všetky tri články ho dedia. Každý vie to isté: buď žiadosť vybaví, alebo ju posunie ďalej.
  2. Reťaz drží sama seba: vedúci má odkaz na riaditeľa, riaditeľ na predstavenstvo. Posledný článok už nedrží nikoho.
  3. Prvá žiadosť: 500 eur. Zamestnanec ju podá na začiatok reťaze a viac o nej nevie.
  4. Vedúci má limit tisíc, takže je to jeho prípad. Vybaví ju sám a ďalej nejde nič — riaditeľ ani predstavenstvo o nej nikdy nepočuli.
  5. Druhá žiadosť: osemtisíc. Zamestnanec ju podáva na to isté miesto ako predtým.
  6. Nad jeho limit. Vedúci nerozhoduje a ani neodmieta — jednoducho ju posunie ďalej.
  7. Riaditeľ má limit desaťtisíc, takže tu sa reťaz zastaví. Predstavenstvo sa o tejto žiadosti nedozvie.
  8. Tretia žiadosť: dvestotisíc. Znova to isté miesto.
  9. Vedúci ju posunie ďalej.
  10. Riaditeľ tiež — a teraz je na rade posledný článok.
  11. Predstavenstvo zvládne všetko, takže reťaz končí tu. Práve preto musí posledný článok zobrať čokoľvek — inak by žiadosť prepadla na koniec a nestalo by sa nič.
  12. Zamestnanec vždy volal to isté miesto a ani raz sa nedozvedel, kto to vybaví. Reťaz sa dá preskladať alebo predĺžiť bez toho, aby o tom vedel — a to je celý zmysel vzoru.

Kedy použiť

  • Kto požiadavku vybaví, sa rozhoduje až za behu. Odosielateľ pozná len začiatok reťaze a nemusí vedieť, kto z nej je práve na rade.
  • Spracovateľov treba pridávať a preskladávať bez zásahu do volajúceho. Reťaz sa poskladá inde a odosielateľ o tom nemá ako vedieť.
  • Podmienky by inak boli jeden dlhý reťazec vetiev. Každá vetva sa stane vlastnou triedou, ktorá vie jediné: či to je jej prípad.
  • Požiadavka môže prejsť viacerými miestami a každé z nich má právo ju zastaviť. Kontrola prístupu, filtrovanie, logovanie — všetko sú články jednej reťaze.

Pasce

  • Požiadavka môže prepadnúť na koniec a nestane sa nič. Reťaz nikoho nenúti odpovedať, takže bez posledného článku, ktorý zoberie všetko, zmizne bez stopy aj bez chyby.
  • Nikto nezaručí, že reťaz je celá. Chýbajúci odkaz na nasledujúceho ju ticho ukončí uprostred a prejaví sa to len tým, že sa niečo nestalo.
  • Ladenie je ťažké práve preto, že nikto nevie, kto to vybaví. Cestu požiadavky treba prejsť článok po článku a v kóde nie je jediné miesto, kde by bola vidieť celá.
  • Poradie článkov je skryté pravidlo. Reťaz funguje, kým ju niekto nepreskladá — a poradie pritom nikde nie je napísané ako podmienka.
  • Zamieňa sa s Decoratorom. Dekorátor pridá chovanie a pustí volanie ďalej vždy; článok reťaze sa rozhoduje, či ho pustí, a spravidla ho zastaví. Rovnaká štruktúra, opačný zámer.
  • Cyklus v reťazi ju zacyklí. Keď sa dva články odkazujú navzájom, požiadavka medzi nimi behá donekonečna a nič ju nezastaví.
  • Dlhá reťaz stojí čas pri každej požiadavke. Prejde sa celá aj vtedy, keď ju vybaví až posledný — a pri každom volaní znova.