State

Situace

V systému se nachází třída, jejíž chování je velmi silně závislé na jejím vnitřním stavu. Zbytek systému má být od tohoto stavu odstíněn.

Problém

Typická špatná implementace tohoto chování se opírá o množství podmínek, jejichž údržba je obtížná. Všechny stavy třídy jsou smíchané dohromady, i když by správně měly být odděleny.

Řešení

Na základě vnitřních stavů se vytvoří hiearchie tříd, které implementují společné rozhraní. Do třídy, která tento vnitřní stav obsahuje, bude obsahovat proměnnou, obsahující právě jednu instanci třídy z této hiearchie, tedy vnitřní stav. Všechny metody, které závisí na vnitřním stavu, jsou na tento stav delegovány.

Změna vnitřního stavu se provádí výměnou objektu, který představuje vnitřní stav.

Varianty
  • změny vnitřního stavu provádí ostatní třídy
  • vnitřní stav mění třída sama
  • změna vnitřního stavu probíhá automaticky na základě hodnot vstupních parametrů
UML diagramy

diagram tříd

sekvenční diagram

Související vzory
  • Strategy – konkrétní strategii určuje klient
Příklad

Následuje jednoduchý příklad implementace tohoto vzoru v programovacím jazyce Java.

Vnitřní stavy

kód v jazyce Java - Zobrazit

  1. /**
  2.  * Nálada (obecný vnitřní stav).
  3.  *
  4.  * @author Vojtěch Hordějčuk
  5.  */
  6. public interface StateOfMind
  7. {
  8.   /**
  9.    * Vyjádří daný pocit.
  10.    */
  11.   public void express();
  12. }
  13.  
  14. /**
  15.  * Pocit štěstí (konkrétní vnitřní stav).
  16.  *
  17.  * @author Vojtěch Hordějčuk
  18.  */
  19. public class HappyState implements StateOfMind
  20. {
  21.   @Override
  22.   public void express()
  23.   {
  24.     System.out.println("Jsem veselý :)");
  25.   }
  26. }
  27.  
  28. /**
  29.  * Pocit smutku (konkrétní vnitřní stav).
  30.  *
  31.  * @author Vojtěch Hordějčuk
  32.  */
  33. public class SadState implements StateOfMind
  34. {
  35.   @Override
  36.   public void express()
  37.   {
  38.     System.out.println("Jsem smutný :(");
  39.   }
  40. }
Kontext

Kontext je třída, jejíž stav je reprezentován instancí nějakého vnitřního stavu.

kód v jazyce Java - Zobrazit

  1. /**
  2.  * Třída s vnitřním stavem.
  3.  *
  4.  * @author Vojtěch Hordějčuk
  5.  */
  6. public class Context
  7. {
  8.   /**
  9.    * aktuální pocit
  10.    */
  11.   private StateOfMind state;
  12.  
  13.   /**
  14.    * Vytvoří novou instanci.
  15.    */
  16.   public Context()
  17.   {
  18.     this.state = new HappyState();
  19.   }
  20.  
  21.   /**
  22.    * Vyjádří daný pocit.
  23.    */
  24.   public void express()
  25.   {
  26.     System.out.println("Nyní vyjádřím svůj pocit.");
  27.     state.express();
  28.   }
  29.  
  30.   /**
  31.    * Nastaví první stav.
  32.    */
  33.   public void beHappy()
  34.   {
  35.     System.out.println("Teď budu veselý.");
  36.     this.state = new HappyState();
  37.   }
  38.  
  39.   /**
  40.    * Nastaví druhý stav.
  41.    */
  42.   public void beSad()
  43.   {
  44.     System.out.println("Teď budu smutný.");
  45.     this.state = new SadState();
  46.   }
  47. }
Test

kód v jazyce Java - Zobrazit

  1. public static void main(String[] args)
  2. {
  3.   // vytvořit kontext
  4.  
  5.   Context context = new Context();
  6.  
  7.   // nastavit první stav (štěstí)
  8.  
  9.   context.beHappy();
  10.   context.express();
  11.  
  12.   // nastavit druhý stav (smutek)
  13.  
  14.   context.beSad();
  15.   context.express();
  16. }

Reference