Návrhové vzory pro GUI RICHARD LIPKA 19. 3. 2018
Základní struktura GUI Vstup od uživatele Propojení s periferiemi Zpracování událostí Co se má stát po vstupu Spojení s jádrem programu Užitečná činnost Zpracování vstupu (od OS) Grafický subsystém Vykreslení obrazu Reakce na události Vlastní činnost Vykreslování 19.3.2018 UUR - NÁVRH APLIKACE 2
Interakce s uživatelem OS zajišťuje komunikaci s periferiemi Jednoduchá komunikace Stisknutí tlačítka Pohyb myši Jedna jasná událost z okolí Gesta Dvojklik, trojklik Gesta myši, drag and drop Více dotyková zařízení Klávesové kombinace Stisk tlačítka Kinect a podobná zařízení gesta rukou Potřebuji je rozpoznávat V ideálním případě jejich rozpoznání zajistí OS / platforma Kde to jde reagovat na gesta - univerzálnější Správa přerušení (HW) Ovladač zařízení Detekce gest Vznik události Obsluha OS Platforma Aplikace 19.3.2018 UUR - NÁVRH APLIKACE 3
Událostní smyčka 1 proces (CPU) může vykonávat jen 1 program Pevně daná posloupnost akcí Můžu se ptát jestli proběhla událost potřebuji nekonečný cyklus Proces musí zajistit Sledování událostí Rozpoznání gest (pokud je nedělá někdo za něj) Reakci na události Aktualizaci vzhledu Včetně změn kurzoru, podbarvení tlačítek Smyčka funguje ve většině technologií sama Nenarušovat ji, jen využít Pokračovat? Vezmi událost z fronty Je tam? ne ano ano Překresli okno Zavolej obsluhu ne 19.3.2018 UUR - NÁVRH APLIKACE 4
Zpracování události Každé události je třeba nastavit obsluhu Běží uvnitř smyčky událostí krátká a rychlá (nebo nové vlákno)! jinak GUI zamrzne! Platforma obvykle dokáže zpracovat základní gesta Kliknutí na obrazovku Událost myši pozice, identifikace tlačítka Lze získat z OS / ovladače příslušného zařízení Stisk tlačítka V důsledku stisknutí levého tlačítka myši nad komponentou tlačítko (nebo stisknutí klávesnicí, nebo stisknutí na dotykovém zařízení) Platforma musí zjistit že k ní došlo (OS nerozumí vnitřku okna, pokud není nativní) Platforma může vytvořit odpovídající událost, reagovat na ni (univerzálnější) Pozor, gesto může existovat s původní událostí lze reagovat na obojí (ale chci to?) 19.3.2018 UUR - NÁVRH APLIKACE 5
Důležité aspekty vývoje Návrh je naprosto nezbytný Nejdřív na papíře / v modelovacím nástroji! Nikdy bez spolupráce s uživatelem! (nebo alespoň bez dobré znalosti jeho práce) Iterativní design Prvotní návrh málokdy funguje, počítat s tím Chyby a problémy se často projeví až při testování / skutečném používání obtížné testovat GUI bez funkčního backendu Všechny fáze konzultovat s uživatelem / testovat Držet se zvyklostí platformy Často existují odpovídající manuály (Windows, Mac OS, Android) Uživatel se v aplikaci snáze vyzná Pozor na vstupy Cokoliv co uživatel zadává je podezřelé testovat, kontrolovat, upozorňovat 19.3.2018 UUR - NÁVRH APLIKACE 6
Důležité aspekty vývoje Pozor na zpracování chyb Nikdy je neskrývejte Nezobrazujte uživateli nic čemu nerozumí logy pro vývojáře, srozumitelná chybová hlášení Stabilní aplikace Uživatel si vytváří mentální mapu aplikace neměnit pozice prvků, neskrývat - nepomáhá to Uživatele lze sledovat Existuje řada studií o tom kam uživatelé koukají, co vidí dřív a co později Aplikace může logovat své používání je poznat co a jak se používá 19.3.2018 UUR - NÁVRH APLIKACE 7
Řízení aplikace - doporučení Umožněte ovládání myší i klávesnicí Klávesové zkratky urychlují práci Myš občas nefunguje nespoléhat jen na ni (podle možností) Popisujte srozumitelně všechny prvky Jasné popisy tlačítek a menu Kontextová nápověda (popup) když je text moc dlouhý Vratné akce Umožněte uživateli vracet jednotlivé úklony ( zpět ve Wordu) Nepovolte destruktivní akce bez ověření Okamžitá reakce Nikdy nenechte GUI zamrznout, vždy zobrazujte jak dlouho bude ještě pracovat (nebo alespoň že je vytížené) Umožněte zastavení probíhajících činností bez poškození dat Konzistentní GUI Seskupujte související ovládací prvky Reagujte na chyby vždy stejně dialog, pomocný výpis, stavová lišta 19.3.2018 UUR - NÁVRH APLIKACE 8
Dělení aplikace na vrstvy Zapouzdření = komunikace jen přes definovaná rozhraní implementace je skrytá před ostatními vrstvy jsou na sobě nezávislé snadná záměna a spolupráce na jednotlivých částech aplikace Soudržnost (cohesion) : 1 entita, 1 úkol Minimální provázanost (loose coupling): kde to jde vyhnout se závislostem Obojí lze měřit, nespoléhat slepě na metriky A D A D B E B E C F C << Interface >> F 19.3.2018 UUR - NÁVRH APLIKACE 9
Vrstvení aplikace třívrstvá architektura Prezentační vrstva Uživatelské rozhraní Přijímá pokyny a převádí výsledky do uživatelem pochopitelné podoby Logická vrstva Aplikační procesy, výpočty Datová vrstva Ukládání a získávání dat (databáze / soubory) 19.3.2018 UUR - NÁVRH APLIKACE 10
Návrhové vzory Poslední přednáška OOP! Vzorečky pro tvorbu programů Pokrývají základní situace které se opakovaně objevují Usnadňují komunikaci mezi vývojáři a návrháři (můžu pojmenovat i složitější struktury) Vyzkoušená a funkční řešení urychlují návrh a vývoj!!! Pokud jsou správně použity!!! Je dobré je znát a rozumět jim, není nutné je používat vždy (výhody se obvykle projeví u větších a dlouhodobě udržovaných projektů) Z roku 1995 (GoF) - Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides: Design Patterns: Elements of Reusable Object-Oriented Software, 1995 Pro jazyk C++ - řada věcí v Javě zadarmo podporována návrhem jazyka 23 vzorů, 3 skupiny V knihovně česká verze (Návrh programů pomocí vzorů : stavební kameny objektově orientovaných programů) 19.3.2018 UUR - NÁVRH APLIKACE 11
Návrhové vzory potřebné pro GUI Architektonické vzory (doplněné později) Model-View-Controler Model-View-Presenter Model-View-ViewPresenter Konstrukční vzory Tovární metoda (Factory) Postupem času se objevily další vzory Strukturální vzory Kompozit [Strom, graf] (Composite) Vzory chování Pozorovatel (Observer) Prostředník (Mediator) Iterátor (Iterator) Strategie (Strategy) Ozdoba (Decorator) Velké množství informací je možné nalézt na internetu (bohužel obvykle bez podrobného rozboru) http://en.wikipedia.org/wiki/software_design_pattern http://www.tutorialspoint.com/design_pattern/index.htm 19.3.2018 UUR - NÁVRH APLIKACE 12
Pozorovatel (Observer) Univerzální obsluha událostí Pozorovatel (obvykle rozhraní nebo abstraktní třída) a jeho potomci Metoda notify() pro oznámení změny Pozorovaný Reference na pozorovatele Registrace a deregistrace Může vést k memory leakům, pokud se pozorovatelé neodhlašují Základ pro složitější vzory V Javě třída Observable a rozhraní Observer Obvykle je třeba vlastní implementace nechci dědit od Observable Observable addobserver() deleteobserver (Observer o) haschanged() clearchanged() setchanged() notifyobservers() notifyobservers (Object o) Observer update (Observable o Object arg) 19.3.2018 UUR - NÁVRH APLIKACE 13
Prostředník (Mediator) Komunikace mezi objekty aniž by na sebe měly referenci Zdroj odesílá zprávy do schránky Cíle si zprávy ze schránky vybírají Zdroj a cíl může být stejný objekt, peer to peer komunikace Umožňuje asynchronní komunikaci větší míra oddělení vrstev Běžný ve složitějších frameworcích (OSGi) Mediator a Colleague (Producer a Consumer) obvykle reprezentováni rozhraním Pro příjem zpráv lze využít vzor Observer Mediátor obvykle umožňuje filtrování zpráv pro posluchače (podle zdroje nebo obsahu zprávy) 19.3.2018 UUR - NÁVRH APLIKACE 14
Model-View-Controller (MVC) Klasický model komunikace počítače s člověkem, nejstarší Dělí GUI na 3 moduly Model: udržuje stav systému, obsahuje logiku aplikace aktivní nebo pasivní View: zobrazuje systém uživateli na základě informací z modelu Controller: Přijímá vstup od uživatele, provádí změny v modelu, volí vhodné view pro výstup Typické pro webové aplikace Model backend aplikace View zobrazované html Controller zpracování vrácených formulářů Velmi často hierarchický (pro každou komponentu) 19.3.2018 UUR - NÁVRH APLIKACE 15
Model-View-Presenter (MVP) Podobný jako MVC, view může být pasivní Model: rozhraní pro přístup k datům, logika aplikace View: Pasivní rozhraní které zobrazuje data Supervising controller: view navíc zpracovává vstup od uživatele Presenter: Získává data z modelu a předává je view Pokud je víc view, pro každé musí být vlastní presenter 19.3.2018 UUR - NÁVRH APLIKACE 16
Model-View-ViewModel (MVVM) Nejnovější, vytvořený v Microsoft Model: doménový model, data, logika aplikace View: prezentační vrstva - vstup i výstup pro uživatele ViewModel: abstrakce view pro model binding dat mezi view a viewmodel obraz vstupních a výstupních polí (nepotřebuje referenci na view, binding zajistí framework) může být doplněn o separátní controllery 19.3.2018 UUR - NÁVRH APLIKACE 17
MVC vs. MVP vs. MVVM Model a View víceméně vždy totéž Model: data a logika aplikace View: to co vidí uživatel a s čím může pracovat (formuláře, tlačítka, stránky na webu, ) Controler: Ovladače pro uživatele, přímo manipuluje s modelem V klasické podobě přímo ovládací prvky V moderní podobě třídy zpracovávající vstupy Presenter: Překladač modelu pro view, reference mezi view a modelem, synchronní komunikace ViewModel: Překladač view pro model, binding zajišťuje aktualizaci dat detaily implementace viz http://joel.inpointform.net/software-development/mvvm-vs-mvp-vs-mvc-the-differences-explained/ 19.3.2018 UUR - NÁVRH APLIKACE 18
Odbočka Novinky ve světě JavaFX Změna struktury Java JDK a číslování verzí Půlroční interval vydávání, nové číslování verzí, snaha o menší jádro Javy (Java 10 18.3 někdy brzy, Java 11-18.9) JavaFX, Java Web Start, Applet odděleny do samostatných modulů (snaha totéž udělat i se Swing, AWT, ) Kotlin a TornadoFX Jazyk nad JRE Od autorů IntelliJ IDEA Snaha o snazší synxaci a přehlednější kód FXGL - Knihovna pro herní aplikace Podpora Javy a Kotlinu Paralaxní scrollling, částicové systémy, manipulace s texturami, základní fyzika (kolize, Box2D), podpora pro AI (gdx-ai), hledání cest, 19.3.2018 UUR - NÁVRH APLIKACE 19
Dekompozice aplikace - příklad GUI Add Button Table Store Button Volá metodu store() z rozhraní Controller Zobrazuje Vytváří instance (volá konstruktor nebo továrnu) Datový model - kolekce Task Person Department Odpovídá struktuře databáze nebo souborů s daty Volá metodu create() z rozhraní Create new Store files Ukládá data na disk / do DB 19.3.2018 UUR - NÁVRH APLIKACE 20
Tovární metoda Metoda vytvářející instanci objektu místo konstruktoru továrna může rozhodnout o třídě vytvářeného objektu Klient neví nic o způsobu vytváření objektu Zná jen rozhraní objektu který továrna vrací Může odstínit od složitých konstruktorů Za běhu lze rozhodnout o použité implementaci předáním vhodné reference (místo podmínky) 19.3.2018 UUR - NÁVRH APLIKACE 21
Iterátor Vzor pro průchod všemi prvky daného kontejneru Skrývá implementaci kontejneru (nemusím vědět jakým způsobem ho procházet jednoduché u polí, těžší u stromů) Jen pokud je možné jednoznačně určit pořadí prvků Může existovat několik způsobů procházení V Javě umožňuje tvorbu zkráceného for cyklu nebo použití foreach() V Javě rozhraní Iterator hasnext() getnext() remove() nemusí být podporovaná funkce Pro seznamy ListIterator<E> Rozhraní Iterable pro objekty přes které lze iterovat 19.3.2018 UUR - NÁVRH APLIKACE 22
Kompozit Umožňuje zacházet se skupinou objektů jako s jedním objektem Vytváří stromovou strukturu (prvkem kompozitu mohou být další kompozity) Při změně kompozitu nemusím měnit klienta Typicky okno v GUI, geometrické objekty složené z grafických primitiv 19.3.2018 UUR - NÁVRH APLIKACE 23
Strategy Definována sada algoritmů které Mohou být zaměňovány Za běhu programu si lze vybrat který bude použit Algoritmy ukryty za rozhraním jednotný přístup Užitečné pro Layoutování prvků v okně Práci s různými typy souborů Řazení podle různých pravidel Mění chování objektu, ale ne jeho vzhled (ve smyslu API) na venek 19.3.2018 UUR - NÁVRH APLIKACE 24
Dekorátor (Wrapper) Doplnění nebo úprava funkcionality danému objektu, aniž by se změnilo jeho standardní chování Může fungovat staticky i dynamicky (přiřazení za běhu) Nemění se původní třída Lze na sebe vršit několik dekorátorů Znáte z I/O proudů, třída Optional<T> V GUI např. doplnění posuvníků nebo rámečků 19.3.2018 UUR - NÁVRH APLIKACE 25
Dekorátor 1. Dekorovaný prvek a dekorátor sdílejí stejné rozhraní (nebo jsou potomky téže třídy) 2. Dekorátor má referenci na dekorovaný objekt (obvykle získaný v konstruktoru) 3. Všechna volání předává dekorovanému objektu 4. Implementace dekorátoru překrývá metody které je třeba měnit nebo přidává nové 19.3.2018 UUR - NÁVRH APLIKACE 26
Lambda výrazy V Javě od verze 1.8 Lze chápat jako anonymní metody Hodí se při potřebě anonymní vnitřní třídy s jedinou metodu Umožňují použít jako parameter metody jinou metodu Hodí se pro Porovnávání (tvorba komparátoru) Zpracování celé kolekce (metoda foreach()) Reakce na události (jednoduchý obslužný objekt) 19.3.2018 UUR - NÁVRH APLIKACE 27
Lambda výrazy - zápis (parametry) -> {tělo metody} Parametry: seznam parametrů (a typů pokud je třeba) Obvykle si překladač dokáže typ parametru odvodit Tělo metody: blok který se má provést Lze použít tam, kde se jako parametr očekává instance rozhraní s jedinou metodou ( functional interface ) Z definice metody se odvozují typy Příklad: Pro interface Comparator, metodu compare() (name1, name2) -> { if (name1.length() == name2.length()) { return 0; } if (name1.length() > name2.length()) { return -1; } else { return 1; } } 19.3.2018 UUR - NÁVRH APLIKACE 28
Lambda výrazy příklad II Lambda výraz bez implementace rozhraní (int x, int y) -> x+y (x, y) -> { return x+y; } (int x, int y) -> { System.out.println(x+y); return x+y; } Lambda výraz a rozhraní @FunctionalInterface interface Converter { double convert(double input); } static double convert (Converter converter, double input) { return converter.convert(input); } System.out.println (convert(input -> (input-32)*5.0/9.0, 98.6)); 19.3.2018 UUR - NÁVRH APLIKACE 29
Děkuji za pozornost 19.3.2018 UUR - NÁVRH APLIKACE 30