====== 7 - Strategy, State ====== Stáhněte si archiv se šablonami tříd pro {{:courses:b6b36omo: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.