všetky vzory

Observer

Rozpošle zmenu stavu všetkým, ktorí sa na jeho odber prihlásili.

class Order {  #observers = new Set();  #state = 'new';   subscribe(observer) {    this.#observers.add(observer);  }   unsubscribe(observer) {    this.#observers.delete(observer);  }   pay() {    this.#state = 'paid';    this.#notify();  }   #notify() {    for (const observer of this.#observers) {      observer.update(this);    }  }} const order = new Order();order.subscribe(new EmailAlert());order.subscribe(new AuditLog());order.subscribe(dashboard); order.pay();order.unsubscribe(dashboard);order.pay();

Celý priebeh v texte (9 krokov)
  1. Order má prázdny zoznam odberateľov. Zatiaľ nie je s nikým spojený — a o žiadnej z tých tried nevie nič.
  2. EmailAlert sa prihlási na odber. Až týmto volaním pribudne do zoznamu referencia na neho.
  3. AuditLog a Dashboard tiež. Order teraz drží tri referencie — a nič viac.
  4. Objednávka sa zaplatila. Stav Order sa zmenil.
  5. Jedno zavolanie notify() a udalosť letí všetkým naraz. Order pritom nemenoval ani jednu triedu.
  6. Každý si ju spracuje po svojom — jeden pošle mail, druhý zapíše log, tretí prekreslí graf.
  7. Dashboard sa odhlási. Zo zoznamu zmizne jeho referencia aj lanko na neho.
  8. Ďalšia udalosť už ide len dvom. Kód Order sa pritom nezmenil ani o znak.
  9. Pridať štvrtého odberateľa znamená nedotknúť sa Order. To je celý zmysel vzoru.

Kedy použiť

  • Zmena v jednom objekte má rozhýbať ďalšie, no nie je vopred jasné ktoré ani koľko.
  • Odberatelia sa majú pripájať a odpájať za behu, nie natvrdo v kóde.
  • Odosielateľ nemá poznať triedy, ktoré na jeho udalosť reagujú.

Pasce

  • Poradie doručenia nie je zaručené. Kto sa oň oprie, má skrytú väzbu.
  • Zabudnuté odhlásenie je únik pamäte — subjekt drží referenciu a odberateľ nezmizne.
  • Udalosť, ktorá vyvolá ďalšiu, sa ťažko ladí a cyklus sa prezradí až zamrznutím.
  • Oznámenie bez dát prinúti odberateľa pýtať sa subjektu — a väzba je naspäť.