všetky vzory

Command

Zabalí volanie do objektu, ktorý sa dá odložiť, zaradiť do frontu alebo vrátiť.

class Prikaz {  vykonaj() { throw new Error('abstraktná metóda'); }  vrat() { throw new Error('abstraktná metóda'); }} class VlozText extends Prikaz {  constructor(dokument, text) {    super();    this.dokument = dokument;    this.text = text;  }   vykonaj() {    this.dokument.vloz(this.text);  }   vrat() {    this.dokument.zmaz(this.text.length);  }} class Tlacidlo {  historia = [];   stlac(prikaz) {    prikaz.vykonaj();    this.historia.push(prikaz);  }   spat() {    const posledny = this.historia.pop();    posledny.vrat();  }} const tlacidlo = new Tlacidlo();tlacidlo.stlac(new VlozText(dokument, 'ahoj'));tlacidlo.stlac(new VlozText(dokument, ' svet'));tlacidlo.spat();   // volanie sa dá vrátiť, lebo je to objekt

Celý priebeh v texte (11 krokov)
  1. Prikaz je abstraktný a vie dve veci: vykonať sa a vrátiť sa späť. To druhé je pri obyčajnom volaní nemysliteľné — volanie po sebe nenechá nič, čo by sa dalo vrátiť.
  2. Používateľ klikne na tlačidlo.
  3. A tu je celý vzor: z toho kliku sa stane objekt. Tlačidlo nič nevykoná — vyrobí príkaz typu VlozText a ten je odteraz vec, ktorú možno držať v ruke.
  4. Až potom povie príkazu, nech sa vykoná. Text pribudne v dokumente.
  5. A príkaz zostáva v histórii. Toto je ten rozdiel: obyčajné volanie by v tejto chvíli už neexistovalo.
  6. Druhý klik.
  7. Druhý príkaz — nová instancia s vlastným textom, uložená vedľa prvej.
  8. Aj ten sa vykoná.
  9. A teraz to, čo je bez vzoru nemožné: používateľ dá krok späť.
  10. Tlačidlo vezme posledný príkaz z histórie a povie mu, nech sa vráti. Ten vie, čo urobil, takže vie aj ako to odčiniť — a potom z histórie zmizne.
  11. V histórii zostal prvý príkaz a druhý je odčinený. Volanie zabalené do objektu sa dá odložiť, zaradiť do frontu, zopakovať aj vrátiť — obyčajné volanie zmizne, len čo prebehne.

Kedy použiť

  • Akcia sa má dať vrátiť späť. Volanie po sebe nenechá nič, objekt áno — a práve preto sa doň dá pridať aj opačný krok.
  • Vykonanie treba oddeliť od okamihu, keď o ňom padlo rozhodnutie. Príkaz sa dá zaradiť do frontu, naplánovať alebo poslať inam a vykonať neskôr.
  • To isté má spúšťať viacero miest. Tlačidlo, klávesová skratka aj menu držia ten istý príkaz a nikto z nich nevie, čo sa vlastne stane.
  • Postupnosť krokov sa má dať zopakovať alebo zaznamenať. Zoznam príkazov je história, makro aj protokol o tom, čo sa udialo.
  • Volajúci nemá vedieť, kto prácu urobí. Drží príkaz, nie príjemcu — a ten sa dá vymeniť bez toho, aby o tom vedel.

Pasce

  • Vrátenie späť je ťažšie, než vyzerá. Príkaz si musí zapamätať dosť na to, aby zmenu odčinil — a pri niektorých operáciách to znamená uložiť celý predošlý stav.
  • Trieda na každú akciu. Pri desiatich operáciách je to desať tried a väčšina z nich má jednu metódu s jedným riadkom.
  • História rastie a nikto ju neupratuje. Každý príkaz drží svoje dáta aj príjemcu, takže sa nedá uvoľniť nič, čo je v nej.
  • Zamieňa sa so Strategy. Stratégia hovorí, ako niečo urobiť, a vymieňa sa; príkaz hovorí, čo sa má stať, a odkladá sa. Prvá je algoritmus, druhý je požiadavka.
  • Vrátenie v inom poradí rozbije stav. História predpokladá, že sa kroky vracajú odzadu — kto vráti prostredný, dostane dokument, aký nikdy neexistoval.
  • Príkaz drží príjemcu dlhšie, než treba. Kým je v histórii, drží aj objekt, nad ktorým pracoval, a ten nezanikne ani po zavretí.