====== 7 - Strategy, State ======
Stáhněte si archiv se šablonami tříd pro {{:courses:a7b36omo:labs:seminar7.zip|7. cvičení}}.
===== 1. Úloha na cvičení =====
Třída Employee představuje zaměstance.
Pro každého zaměstnance můžeme vypočítat
* mzdu (metoda ''salary()'')
* zjistit způsob jejího vyplacení (metoda ''payout()'')
V první fázi uvažujeme dva typy zaměstnanců:
* plný úvazek (''STANDARD_EMPLOYEE''),
* částečný úvazek (''PT_EMPLOYEE'')
Každý zaměstnanec na plný úvazek dostává pevnou částku 20000 Kč.
Částečný úvazek je ohodnocen 150 Kč/h.
Platby jsou prováděny pro oba typy zaměstnanců bankovním převodem (''payout()'' vrací ''"bank transfer"'').
== 1. Naivní řešení pomocí switch/if-else: ==
* naimplementujte metody ''salary()'' a ''payout()'',
* přidejte nový typ zaměstnance dobrovolníka (''VOLUNTEER_EMPLOYEE''). Je placen pevnou částkou 2000 Kč v hotovosti (''payout()'' vrací ''"cash"''),
* diskutujte problémy zvoleného postupu.
* {{:courses:a7b36omo:labs:solution:seminar7solution1.zip|řešení}}
== 2. Řešení pomocí dědičnosti: ==
* řešte původní problém důsledným použitím dědičnosti,
* opět přidejte dobrovolníka,
* přidejte rovněž možnost obou typů výplaty pro všechny typy zaměstnanců,
* diskutujte problémy zvoleného postupu. Jaká je výška hierarchie tříd? O kolik se v nejhorším případě zvýší počet tříd přidáním dalšího typu uživatele? Jak to bude vypadat s počtem tříd, pokud přidáme novou metodu ''phone()'', která zjistí, zda má zaměstnanec dostat služební telefon (dostanou jej všichni na plný úvazek a zaměstnanci na částečný s platem > 10000 Kč).
* {{:courses:a7b36omo:labs:solution:seminar7solution2.zip|řešení}}
== 3. Řešení pomocí skládání (vzor Strategie): ==
* řešte pomocí vzoru strategie,
* přidejte dobrovolníka a obecný typ výplaty,
* diskutujte. Zaměřte se zejména na růst počtu tříd při přidávání nových typů uživatelů a metod. {{:courses:a7b36omo:labs:strategy.jpg?700|}}
* {{:courses:a7b36omo:labs:solution:seminar7solution3.zip|řešení}}
===== 2. Úloha - State =====
* Vytvořte rozhraní
public interface State {
public void doAction(Context context);
}
* Vytvořte třídu ''StartState'' implementující rozhraní ''State''. Metoda ''doAction()'' vypisuje ''"Player is in start state"'' a kontextu nastavuje instanci ''StartState'' jako aktuální stav. Metoda ''toString()'' vypisuje ''"Start State"''.
* Vytvořte třídu ''StopState'' implementující rozhraní ''State''. Metoda ''doAction()'' vypisuje ''"Player is in stop state"'' a kontextu nastavuje instanci ''StopState'' jako aktuální stav. Metoda ''toString()'' vypisuje ''"Stop State"''.
* Implementujte třídu ''Context''. Kontext bude uchovávat hodnotu typu ''State''.
* Otestujte, vytvořte program s následujícím výstupem:
Player is in start state
Start State
Player is in stop state
Stop State
* Implementujte metodu ''goNext()'', která bude sloužit k přepínání mezi stavy. Diskutujte situaci, pokud budete mít více než dva stavy. {{:courses:a7b36omo:labs:state.jpg?700|}}
* {{:courses:a7b36omo:labs:solution:seminar7solution4.zip|řešení}}
State je podobný návrhovému vzoru Strategy, odlišují se však účelem. State je více dynamický.
Objekty State bývají často implementovány jako Singleton.