===== 6 - Návrhové vzory State a Strategy ===== ==== Možné řešení z minulého cvičení ==== [[https://gitlab.fel.cvut.cz/B171_B6B36OMO/seminar/tree/master/cv5.1_solution|]] [[https://gitlab.fel.cvut.cz/B171_B6B36OMO/seminar/tree/master/cv5.2_solution|]] ===== Teorie ===== ==== Vzor Stav ==== === Problém === Systém musí řešit přechody stavů mezi stavy, ve kterých se nachází a stavy následují jedn po druhém podle definovaných podmínek. Velmi často je takový stavový automat řešený složitým větvením. === Řešení === Vzor Stav navrhuje vytovřit pro všechny stavy samostatné třídy a přemístit logiku týkající se stavů do těchto samostatných tříd. {{:courses:a7b36omo:labs:state.jpg?500|}} ==== Vzor Strategie ==== === Problém === V aplikaci potřebujeme řešit různou logikou podobný cíl. Aplikaci dokonce potřebujeme dále rozvíjet o další logiku, která je doplněním ke stávající logice. Příkladem může být navigace, která původně řešila pouze navigování automobilu, ale časem se ukázalo, že je vhodné aplikaci rozšířit o navigaci pro cyklisty a pak pro chodce. === Řešení === Vzor Strategie navrhuje oddělit jednotlivé významné části logiky, která může mít shodné rozhraní, do samostatných tříd. Tyto tříd implementovat s tímto rozhraním tak, aby byly vzájemně vyměnitelné. {{:courses:a7b36omo:labs:strategy.jpg?500|}} ===== Příklady k řešení ===== Cvičení 6 je zaměřeno na použití návrhových vzorů State a Strategy. Úkolem bude implementovat řízení sekvence semaforů s ohledem na denní dobu. Výsledkem bude model ulice, na které se nacházejí za sebou umístěné semafory. Pro jednoduchost budeme uvažovat stejnou vzdálenost mezi semafory. Každý semafor bude mít cyklus červená - oranžová - zelená - oranžová - červená. Pro každou barvu je určena doba, po kterou má svítit - např. červená 20, zelená 10 časových jednotek, oranžová 2 časové jednotky. Sekvence semaforů bude řízena tak, aby vznikala "zelená vlna" podle denní doby, dopoledne jedním směrem, odpoledne opačným směrem. ==== Implementace ve cvičení 6 bude v následujících krocích ==== 1) Implementace semaforu a přepínání jeho stavů s použitím návrhového vzoru State. Příprava třídy TrafficLight a přípava stavů Stop, Prepare, Go, Attention. {{:courses:a7b36omo:labs:cv6_state_chart_diagram.png?200|}} 2) Implementace ulice se semafory a přípava logiky pro postupné přepínání světel semaforů řídící se algoritmem podle denní doby. Implementace strategií řízení semaforů MorningStrategy a EveningStrategy podle denní doby. Implementace modelu ulice Street, který bude obsahovat seznam za sebou stojících semaforů. Implementace volání logiky zvolené strategie. Pro implementaci použijte předpřipravený maven projekt. [[https://gitlab.fel.cvut.cz/B171_B6B36OMO/seminar/tree/master/cv6_assignment|]] Projekt již obsahuje třídy potřebné pro řešení. Ve třídách Street, EveningStrategy, Go, Prepare, Stop najdete místa označená TODO, která je potřeba implementovat. {{:courses:a7b36omo:labs:cv6_todos.png?500|}} ==== Implementace semaforu s použitím návrhového vzoru State ==== - Implenentujte stavy Stop, Go, Prepare. {{:courses:a7b36omo:labs:cv6_state_class_diagram.png?600|}} - Implementujte přepínání stavů jednoho semaforu v metodě Main.main() a ověřte v unit testech ve třídě TrafficLightTest. Pomocí krokování v debuggeru sledujte činnost kódu. - V metodě Main.main() napište kód pro spuštění automatického přepínání stavů na základě definovaných intervalů pro jednotlivá světla (intervaly jsou definované v enumeraci LightPeriod), logika přepnutí stavu je již součástí vnitřní logiky State. Ověřte správné chování v unit testech ve třídě TraficLightTest. ==== Implementace soustavy semaforů a nastavení logiky ovládání soustavy s použitím vzoru Strategy ==== - implementujte konkrétní EveningStrategy, která bude potomkem třídy Strategy. Tato třída bude implementovat metodu controlTrafic. Strategie má k dispozici posloupnost semaforů (List) a rozhoduje, který semafor začne cyklus (Prepare - Go - Attention - Red). Úkolem EveneningStrategy je řídit semafory tak, aby docházelo k vlně zelených světel zprava doleva. (Na rozdíl od MorningStrategy, která je implementovaná jako vlna zleva doprava). Pro ověření použijte unit test EveningStrategyTest. - ve třídě Street implementujte výběr odpovídající strategie podle aktuálního času. MorningStrategy strategie bude použita dopoledne, po 12té hodině bude použita strategie EveningStrategy. {{:courses:a7b36omo:labs:cv6_strategy_class_diagram.png?500|}} - implementujte v Main třídě a v unit testech StreetTest ověřte funkčnost instance Street a spuštění řízení soustavy 5 semaforů metodou street.runTrafficLights