všetky vzory

State

Vymení chovanie objektu podľa toho, v akom stave sa práve nachádza.

class State {  next(order) { throw new Error('abstraktná metóda'); }} class NewState extends State {  next(order) {    pay();    order.setState(new PaidState());  }} class PaidState extends State {  next(order) {    ship();    order.setState(new ShippedState());  }} class ShippedState extends State {  next(order) {    // final state, nothing switches any further  }} class Order {  #state = new NewState();   setState(state) {    this.#state = state;  }   // Not a single condition. The state decides what happens next.  next() {    this.#state.next(this);  }}

Celý priebeh v texte (11 krokov)
  1. State je abstraktný a tri konkrétne stavy ho dedia. Order pozná len ten abstraktný — o NewState ani ShippedState nevie nič.
  2. Order práve vznikol, takže drží odkaz na stav NewState. Toto je jediné miesto, kde je jeho stav uložený.
  3. Klient zavolá next(). Jediná metóda, žiadny parameter.
  4. Order nerozhoduje o ničom — nemá ani jednu podmienku. Volanie posunie tomu, koho práve drží.
  5. A tu je vzor: stav sám rozhodne, čo bude ďalej, a vymení sa. Klient o tom nepovedal ani slovo — odkaz v komore sa zmenil bez neho.
  6. Klient zavolá next() znova. To isté volanie ako pred chvíľou.
  7. Order ho posunie ďalej — lenže drží už iný stav, takže sa stane niečo iné. Order sa pritom nezmenil ani o písmeno.
  8. A tento stav sa vymení za ShippedState. Prechody sú napísané v stavoch, nie v triede Order.
  9. Tretie volanie, opäť to isté.
  10. ShippedState je koncový stav. Volanie prijme, ale nikam sa neprepne — odkaz v komore zostáva, na aký bol.
  11. To isté volanie urobilo zakaždým niečo iné a Order pritom nemá ani jednu podmienku. Prepnutie riadi stav — presne v tom sa vzor líši od Strategy, kde novú stratégiu podáva klient a kontext ju sám nikdy nevymení.

Kedy použiť

  • Správanie závisí od stavu a stavov je viac než dva — každý sa stane triedou.
  • Tá istá podmienka sa opakuje vo viacerých metódach: je to stav bez triedy.
  • Prechody majú byť napísané a dodržané, nie rozsypané po podmienkach.
  • Stavov pribúda: nový je nová trieda, nie zásah do každej metódy.

Pasce

  • Zamieňa sa so Strategy. Stratégiu podá klient a kontext ju sám nikdy nevymení; stav sa vymieňa sám.
  • Každý stav musí vedieť, kto ide po ňom — nový doprostred znamená zásah do susedov.
  • Pri dvoch stavoch je vzor drahší než jedno „if".
  • Zabudnutý prechod zasekne objekt navždy a nič to nenahlási.
  • Stavy bez vlastných dát sa dajú zdieľať, so stavom nie — zmiešať to je tichá chyba.
  • Prechody sú rozsypané po triedach; cestu z A do C prezradí až prečítanie všetkých.