Návrhové vzory pro GUI RICHARD LIPKA 29. 2. 2016
Nabídka semestrálních prací pro Aimtec 1.
Porovnání plánovaného a skutečného času vývoje v iteraci ◦ Dohledat a zobrazit plánované a skutečné časy vývoje ◦ Data v Excelu a v MS SQL serveru
2.
Zobrazení dat z komitů do CVS ◦ Zobrazení dat o komitech z DB (MS SQL) podle zadaných kritérií
3.
Grafické rozhraní pro branchCheckout ◦ Spouštění a konfigurace Ant skriptů
4.
Grafický monitor pro výkonnostní indikátory DCIx ◦ Zobrazení výkonnostních dat sbíraných za běhu sledované aplikace
29.2.2016
UUR - NÁVRH APLIKACE
2
Skutečně objektový návrh Využití vlastností OOP pro tvorbu přehlednější aplikace ◦ Co nejčitelnější zdrojový text – „společné idiomy“ ◦ Usnadnění testování – snadné mockování, jasná funkcionalita k testování ◦ Usnadnění spolupráce více lidí na jednom projektu – snadná oddělittelnost částí aplikace menší riziko vzniku chyb
Doopravdy využívat možností, které OOP dává, ne jen zabalit algoritmy a data do objektů
29.2.2016
UUR - NÁVRH APLIKACE
3
Využití abstrakcí – OOP vs. OBP Customer name : String
Account 1
1..* balance : long
getName() : String archive() : String
archive() : String 0..*
0..*
0..*
1
Branch
29.2.2016
◦ OOP má usnadnit budoucí změny programu programování proti rozhraní Archiver
<
> 1
0..*
customerList : Customer accountList : Accout branchList : Branch
1
archive() : String
◦ OOP má zlepšit modularitu programu
1 Archiver
manager : String 0..*
Ne všechno co je založeno na objektech je skutečné OOP
1
adddCustomer(Customer) : void addAccount(Account) : void addBranch(Branch) : void
Archivable getArchieveImage() : String
Client
Branch
Account
getArchieveImage() : String
getArchieveImage() : String
getArchieveImage() : String
UUR - NÁVRH APLIKACE
4
Základní struktura GUI Vstup od uživatele ◦ Propojení s periferiemi
Zpracování událostí ◦ Co se má stát po vstupu
Zpracování vstupu (od OS)
Spojení s jádrem programu ◦ „Užitečná činnost“
Grafický subsystém
Reakce na události
◦ Vykreslení obrazu
Vlastní činnost
Vykreslování
29.2.2016
UUR - NÁVRH APLIKACE
5
Interakce s uživatelem OS zajišťuje komunikaci s periferiemi Jednoduchá komunikace ◦ Stisknutí tlačítka ◦ Pohyb myši ◦ … Jedna jasná událost z okolí
Správa přerušení (HW)
Gesta ◦ Dvojklik, trojklik ◦ Gesta myši, drag and drop ◦ Vícedotyková zařízení ◦ Klávesové kombinace ◦ Stisk tlačítka ◦ Kinect a podobná zařízení 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ší
Ovladač zařízení Detekce gest
Platforma Vznik události Obsluha
29.2.2016
UUR - NÁVRH APLIKACE
OS
Aplikace 6
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
ne
Pokračovat? ano Vezmi událost z fronty
Je tam?
ano
Zavolej obsluhu
◦ Včetně změn kurzoru, podbarvení tlačítek …
ne
Smyčka funguje ve většině technologií sama
Překresli okno
Nenarušovat ji, jen využít
29.2.2016
UUR - NÁVRH APLIKACE
7
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?)
29.2.2016
UUR - NÁVRH APLIKACE
8
Ří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 …
29.2.2016
UUR - NÁVRH APLIKACE
9
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é
B A
C
D
F E
snadná záměna a spolupráce na jednotlivých částech aplikace
B
Soudržnost (cohesion) : 1 entita, 1 úkol
A
Minimální provázanost (loose coupling): kde to jde vyhnout se závislostem
D
29.2.2016
UUR - NÁVRH APLIKACE
C << Interface >>
F E
10
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)
29.2.2016
UUR - NÁVRH APLIKACE
11
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ů)
29.2.2016
UUR - NÁVRH APLIKACE
12
Návrhové vzory potřebné pro GUI Architektonické vzory (doplněné později) ◦ Model-View-Controler ◦ Model-View-Presenter ◦ Model-View-ViewPresenter
Strukturální vzory ◦ Kompozit [Strom, graf] (Composite)
Vzory chování ◦ ◦ ◦ ◦ ◦
Konstrukční vzory ◦ Tovární metoda (Factory)
Pozorovatel (Observer) Prostředník (Mediator) Iterátor (Iterator) Strategie (Strategy) Ozdoba (Decorator)
Postupem času se objevily další vzory 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
29.2.2016
UUR - NÁVRH APLIKACE
13
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 Observable se pozorovatelé neodhlašují ◦ addObserver() 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
29.2.2016
◦ deleteObserver (Observer o) ◦ hasChanged() ◦ clearChanged() ◦ setChanged() ◦ notifyObservers() ◦ notifyObservers (Object o)
UUR - NÁVRH APLIKACE
Observer ◦ update (Observable o Object arg)
14
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
29.2.2016
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)
UUR - NÁVRH APLIKACE
15
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ářů
29.2.2016
UUR - NÁVRH APLIKACE
16
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 presentéru
Pokud je víc view, pro každé musí být vlastní presenter
29.2.2016
UUR - NÁVRH APLIKACE
17
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
29.2.2016
UUR - NÁVRH APLIKACE
18
MVC vs MVP vs MVVM Model a View víceméně vždy tototéž ◦ Model: data a logika aplikace ◦ View: to co vidí uživatel a s čím může pracovat (fomulář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/
29.2.2016
UUR - NÁVRH APLIKACE
19
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í
29.2.2016
UUR - NÁVRH APLIKACE
20
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()
29.2.2016
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
UUR - NÁVRH APLIKACE
21
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
29.2.2016
UUR - NÁVRH APLIKACE
22
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ů
29.2.2016
Mění chování objektu, ale ne jeho „vzhled“ (ve smyslu API) na venek
UUR - NÁVRH APLIKACE
23
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 V GUI např. doplnění posuvníků nebo rámečků
29.2.2016
UUR - NÁVRH APLIKACE
24
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é
29.2.2016
UUR - NÁVRH APLIKACE
25
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
29.2.2016
UUR - NÁVRH APLIKACE
26
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á
29.2.2016
UUR - NÁVRH APLIKACE
27
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)
29.2.2016
UUR - NÁVRH APLIKACE
28
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
29.2.2016
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; } }
UUR - NÁVRH APLIKACE
29
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));
29.2.2016
UUR - NÁVRH APLIKACE
30
Děkuji za pozornost
29.2.2016
UUR - NÁVRH APLIKACE
31