SWI041:
Návrhové vzory (Design Patterns) JAK se to obvykle d lá
Zdroje: použity vzory GoF (Gamma, Helm, Johnson, Vlisidess: Design Patterns The Elements of reusable objectoriented software. 1995), Tomáš Richta (Návrhové vzory I., FEL 2005), Petr Šlégr (Návrhové vzory II., FEL 2005) SWI041 - Návrhové vzory
2
Nejprve trochu kontroly Stav projekt
Co to je návrhový vzor? Christopher Alexander: ”Každý vzor popisuje asto se vyskytující problém a poté popisuje jádro ešení tohoto problému tak, aby bylo možno toto ešení opakovan využívat, bez toho, že bychom stejnou v c d lali dvakrát". P estože se tato definice týká návrhu budov, totéž platí pro návrhové vzory p i tvorb program . ešení je zde vyjád eno pomocí pot ebných objekt a zp sobu jejich komunikace. SWI041 - Návrhové vzory
4
Typy vzor Analytické vzory ú etnictví
Architektonické vzory Klient/Server, t i vrstvy, Broker, Model-ViewController (MVC)
Návrhové vzory základní - tvorba, struktura, chování (GoF) paralelní (producent-konzument), reálný as, testovací,...
Programovací vzory, konvence SWI041 - Návrhové vzory
5
Obecné ásti návrhových vzor Jméno vzoru Popis problému Popis ešení D sledky použití
SWI041 - Návrhové vzory
6
Jméno vzoru Termín, p es který se na vzor odvoláváme. Aby se v katalogu vzor dob e a intuitivn hledalo, je volba jména d ležitá a obtížná. P .: Proxy, Iterator
SWI041 - Návrhové vzory
7
Popis problému pro vzor Vyjad uje situaci, kde se použití vzoru hodí. M že se stanovit p íkladem, seznamem podmínek, které musí platit, apod.
SWI041 - Návrhové vzory
8
P : Návrhový vzor “Proxy” Deklarace zám ru: pokud pot ebujeme zástupce objektu, nebo vlastní objekt je n kde jinde, je t žko p ístupný, má být chrán n, ...
Motiva ní p íklad: editor dokumentu by m l um t pracovat s obrázky, ale zobrazení obrázku je náro né - asto posta í náhradník
SWI041 - Návrhové vzory
9
Popis ešení pro vzor Popisuje elementy použité p i ešení a jejich vztahy. Nejedná se o konkrétní implementaci, nebo vzor je pouze šablonou pro ešení.
SWI041 - Návrhové vzory
10
Struktura vzoru Proxy
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
11
D sledky použití vzoru Rozmanité d sledky, které s sebou použití vzoru p ináší - nap . asové a prostorové nároky. Poslouží dob e i p i výb ru alternativ.
SWI041 - Návrhové vzory
12
P íklad použití vzoru Proxy
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
13
P íbuzné strukturální vzory Proxy zastupuje objekt a poskytuje stejné rozhranní jako on Adapter m ní rozhranní, které objekt poskytuje Dekorátor n co p idává
SWI041 - Návrhové vzory
14
SWI041 - Návrhové vzory
15
Kategorie návrhových vzor Vzory pro vytvá ení a manipulaci sreprezentací informace (nap . Abstract Factory, Proxy) Vzory strukturální vyjad ující strukturu implementace (nap . Adapter, Composite) Vzory pro chování (nap . Iterátor)
SWI041 - Návrhové vzory
16
Taxonomie návrhových vzor
Statické
Dynamické
SWI041 - Návrhové vzory
Tvorba
Struktura
Chování
Tovární metoda
Adaptér (t ídní)
Šablonová metoda
Singleton
Adaptér (instan ní), Kompozice
Strategie
17
Problém Je t eba, aby v aplikaci existovala pouze jedna instance n jaké t ídy. Jak to zajistit?
SWI041 - Návrhové vzory
18
Singleton
SWI041 - Návrhové vzory
19
Singleton Vlastnosti: konkrétní typ poskytnuté instance lze ur it za b hu poskytovanou instanci lze m nit bez zm n klientského kódu snadná zm na logiky tvorby - nap . povolení více instancí
P íklad v J2SE: java.lang.Runtime Související vzory: Null Object/Objekt null Object Pool SWI041 - Návrhové vzory
20
Problém Ur itá ást innosti (provád ného algoritmu) je stejná u r zných t íd, ale bázová t ída nezná odlišné chování svých potenciálních podt íd
SWI041 - Návrhové vzory
21
P íklad: komunika ní systém (chat) Server p ijímá r zné typy zpráv a podle nich provádí r zné akce. Server pracuje podle tohoto schématu: kontrola identity a oprávn ní zaslat danou zprávu provedení akce a p íprava odpov di odeslání odpov di a záznam do logu
Kroky 1. a 3. jsou stejné, krok 2. se bude lišit pro každý typ zprávy.
SWI041 - Návrhové vzory
22
Template Method (šablonová metoda) Definuje kostru algoritmu Specifikaci n kterých krok nechává na podt ídách Umož uje modifikovat n které kroky algoritmu bez zm ny jeho struktury
Obrázek p evzat z [GoF] SWI041 - Návrhové vzory
23
Vzor: Builder Deklarace zám ru: odd lení konstrukce složitého objektu od jeho reprezentace pokud má být algoritmus pro vytvá ení složitého objektu nezávislý na vytvá ení ástí pokud lze objekt reprezentovat r znými zp soby
Motiva ní p íklad: editor dokumentu v RTF by m l um t pracovat s r znými reprezentacemi textu (ASCII, TeX, …)
SWI041 - Návrhové vzory
24
Struktura vzoru Builder
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
25
P íklad použití vzoru Builder
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
26
Participanti Builder (TextConverter) specifikuje abstraktní interface pro vytvá ení ástí objekt typu Product.
ConcreteBuilder (ASCIIConverter, TeXConverter, TextWidgetConverter) kontruuje a sestavuje ásti - implementuje interface t ídy Builder udržuje si vytvo enou reprezentaci poskytuje služby pro vyzvednutí produktu (GetASCIIText, GetTextWidget, ...) SWI041 - Návrhové vzory
27
Participanti (pokra .) Director (RTFReader) konstruuje objekty pomocí služeb t ídy Builder
Product (ASCIIText, TeXText, TextWidget) reprezentuje složitý objekt, který je konstruován, t ída ConcreteBuilder vytvá í konkrétní vnit ní reprezentaci zahrnuje t ídy pro definici ástí a služby pro konstrukci celku
SWI041 - Návrhové vzory
28
Kolaborace p i použití Builder
SWI041 - Návrhové vzory
Obrázek p evzat z [GoF]
29
Vzor: Iterator (Cursor) Deklarace zám ru: pro sekven ní p ístup ke složkám složeného objektu bez ohledu na reprezentaci - pokud má být procházen seznam aniž se zabýváme jeho reprezentací (uniformní p ístup pro traverzování agregovaných struktur)
Motiva ní p íklad: sekven ní pr chod seznamy
SWI041 - Návrhové vzory
30
Struktura pro Iterator
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
31
P íklad použití Iterator
SWI041 - Návrhové vzory
Obrázek p evzat z [GoF]
32
Participanti Iterator definuje služby pro p ístup k element m
ConcreteIterator implementuje služby t ídy Iterator udržuje si informace o aktuální poloze
Aggregate definuje služby pro vytvá ení objet typu Iterator
ConcreteAggregate implementuje služby pro t ídu Aggregate SWI041 - Návrhové vzory
33
Implementace template
class List { public: List(long size = DEFAULT_LIST_CAPACITY); long Count() const; Item& Get(long index) const; // ... };
SWI041 - Návrhové vzory
34
Implementace (pokra .) template class Iterator { public: virtual void virtual void virtual bool virtual Item protected: Iterator(); };
SWI041 - Návrhové vzory
First() = 0; Next() = 0; IsDone() const = 0; CurrentItem() const = 0;
35
Implementace (pokra .) template class ListIterator : public Iterator- { public: ListIterator(const List
- * aList); virtual void First(); virtual void Next(); virtual bool IsDone() const; virtual Item CurrentItem() const; private: const List
- * _list; long _current; }; SWI041 - Návrhové vzory
36
Implementace (pokra .) template ListIterator- ::ListIterator ( const List
- * aList ) : _list(aList), _current(0) { }
SWI041 - Návrhové vzory
37
Implementace (pokra .) template void ListIterator- ::First () { _current = 0; }
template void ListIterator- ::Next () { _current++; }
SWI041 - Návrhové vzory
38
Vzor: Interpret Deklarace zám ru: máme zadánu gramatiku jazyka, jehož v ty chceme interpretovat
Motiva ní p íklad: hledání vzorku zadaného regulárním výrazem v et zci (známe gramatiku regulárního výrazu)
SWI041 - Návrhové vzory
39
Struktura vzoru “Interpret” globální kontext
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
40
Gramatika pro regulární výraz expression ::= literal | alternation | sequence | repetition | '(' expression ')' alternation ::= expression '|' expression sequence ::= expression '&' expression repetition ::= expression '*' literal ::= 'a' | 'b' | 'c' | ... { 'a' | 'b' | 'c' | ... }*
SWI041 - Návrhové vzory
41
“Interpret” pro reg. výrazy
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
42
Reprezentace vzorku: raining & (dogs | cats) *
SWI041 - Návrhové vzory
Obrázek p evzat z [GoF]
43
Jiný p íklad: Booleovské výrazy BooleanExp ::= VariableExp | Constant | OrExp | AndExp | NotExp | '(' BooleanExp ')' AndExp ::= BooleanExp 'and' BooleanExp OrExp ::= BooleanExp 'or' BooleanExp NotExp ::= 'not' BooleanExp Constant ::= 'true' | 'false' VariableExp ::= 'A' | 'B' | ... | 'X' | 'Y' | 'Z'
SWI041 - Návrhové vzory
44
T ída BooleanExp class BooleanExp { public: BooleanExp(); virtual ~BooleanExp(); virtual bool Evaluate(Context&) = 0; virtual BooleanExp* Replace(const char*, BooleanExp&) = 0; virtual BooleanExp* Copy() const = 0; };
SWI041 - Návrhové vzory
45
T ída Context class Context { public: bool Lookup(const char*) const; void Assign(VariableExp*, bool); };
SWI041 - Návrhové vzory
46
T ída VariableExp class VariableExp : public BooleanExp { public: VariableExp(const char*); virtual ~VariableExp(); virtual bool Evaluate(Context&); virtual BooleanExp* Replace(const char*, BooleanExp&); virtual BooleanExp* Copy() const; private: char* _name; }; SWI041 - Návrhové vzory
47
Vzor: Abstract factory (Kit) Deklarace zám ru: interface pro vytvá ení kolekcí objekt bez podrobné specifikace jejich struktury
Motiva ní p íklad:
SWI041 - Návrhové vzory
48
Abstract factory (stavebnice)
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
49
P íklad použití
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
50
Vzor: Factory method (virtuální konstruktor) Deklarace zám ru: interface pro vytvá ení a manipulaci s objekty, jejichž konkrétní reprezentaci neznáme
SWI041 - Návrhové vzory
51
Struktura pro “Factory method”
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
52
P íklad použití “Factory method”
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
53
SWI041 - Návrhové vzory
54
P ehled vzor Abstract Factory interface pro vytvá ení sady objekt , bez specifikace konkrétní t ídy
Adapter p evádí interface t ídy na interface o ekávaný klientem - umož uje spolupráci nekomatibilních t íd
Bridge odd luje abstrakci od implementace, takže se mohou nezávsle m nit SWI041 - Návrhové vzory
55
P ehled vzor Builder odd luje konstrukci složeného objektu od jeho reprezentace, takže stejný proces m že vytvá et r zné reprezentace
Chain of Responsibility umož uje propojení zdroje požadavku s p íjemcem tak, že dává více objekt m šanci požadavek zpracovat. Z et zí p íjemce a p edává požadavek mezi nimi.
SWI041 - Návrhové vzory
56
P ehled vzor Command zapouzd uje požadavek jako objekt, a tím umož uje parametrizovat klienty s r znými požadavky, frontami, žurnály
Composite sestavuje objekt do stromové struktury aby reprezentoval vztah celek- ást. Umož uje pracovat s celkem a jeho ástmi uniformním zp sobem
SWI041 - Návrhové vzory
57
P ehled vzor Decorator dynamicky p idává odpov dnost, pružná alternativa pro rozši ování fuk nosti (alternativa k podt ídám)
Facade poskytuje unifikovaný “interface” pro sadu nástroj - podsystém . Poskytuje “interfaceL” vyšší úrovn tak, že použití podsystém je jednodušší.
SWI041 - Návrhové vzory
58
P ehled vzor Factory Method definuje “interface” pro vytvá ení objektu, ale ponechává na podsystémech rozhodnutí, které t ídy použijí (jakou instanci)
Flyweight umož uje podporu efektivního sdílení velkých sad objekt
Interpreter vychází z reprezentace gramatiky jazyka, která umož uje interpretaci v t jazyka SWI041 - Návrhové vzory
59
P ehled vzor Iterator poskytuje sekven ní p ístup k sad element agregovaných objekt bez znalosti reprezentace sady
Mediator definuje object, který zapouzd uje zp sob jak spolu objekty komunikují - místo aby komunikovaly p ímo
SWI041 - Návrhové vzory
60
P ehled vzor Memento bez porušení pravidla zapouzd ení umož uje zapamatování stavu, do kterého se objekt m že pozd ji vrátit
Observer definuje vztah 1:N mezi objekty tak, že pokud jeden objekt zm ní stav, všechny objekty na n m závislé jsou na to upozorn ny a automaticky poopraveny
SWI041 - Návrhové vzory
61
P ehled vzor Prototype specifikuje sadu objekt pot ebných pro vytvo ení instance prototypu a pro kopírování tohoto prototypu
Proxy poskytuje zástupce pro ízení p ístupu k objektu
Singleton zajiš uje,a by t ída m la pouze jednu instanci a poskytuje k ní globální p ístup
SWI041 - Návrhové vzory
62
P ehled vzor State umož uje objektu zm nu chování na základ zm ny jeho stavu
Strategy definuje rodinu algoritm , které jsou podobné a zam nitelné (umož uje zm nu algoritmu nezávisle na klientech)
SWI041 - Návrhové vzory
63
P ehled vzor Template Method definuje kostru algoritmu operace, který pak komunikuje s podsystémy p i vlastním ešení kroky ešení se mohou m nit beze zm ny kostry algoritmu
Visitor reprezentuje operaci, která má být vykonána na elementech struktury objektu - návšt vu struktury objektu
SWI041 - Návrhové vzory
64
P íklad: Šablonová metoda 1 Vytvo íme t ídu Message jako p edka pro všechny typy zpráv public abstract class Message { protected User sender; protected Message (User sender) { this.sender = sender; } //... }
SWI041 - Návrhové vzory
65
P íklad: Šablonová metoda 2 Do t ídy Message p idáme ty metody, jejichž implementace je známa a spole ná všem podt ídám /** Sends response back to the client and make log entry... */ private void sendResponse (String text) { // ... } // ...
SWI041 - Návrhové vzory
66
P íklad: Šablonová metoda 3 Do t ídy Message dále p idáme abstraktní metody, jejichž implementaci zajistí až podt ídy /** Checks user's right to send this message */ public abstract boolean isAllowedFor (User sender); /** Does message's job and return text to be sent to the client as response */ public abstract String process ();
SWI041 - Návrhové vzory
67
P íklad: Šablonová metoda 4 Nakonec p idáme vlastní šablonovou metodu /** This is the TEMPLATE METHOD! It performs algorithm not defined fully in this class. */ public void dispatch () { if (isAllowedFor (sender)) { sendResponse (process ()); else { sendResponse ("Forbidden"); } }
SWI041 - Návrhové vzory
68
P íklad: Šablonová metoda 5 Struktura t ídy Message (rekapitulace): private void sendResponse (String text) {…} public abstract boolean isAllowedFor (User sender); public abstract String process (); public void dispatch () {…}
SWI041 - Návrhové vzory
69
P íklad: Šablonová metoda 6 Tvorba podt ídy: implementuje se pouze to specifické public class KickMessage extends Message { public boolean isAllowedFor (User sender) { return sender.isAdmin (); } public String process() { // delete user from the room... return "User kicked from the room"; } }
SWI041 - Návrhové vzory
70
Šablonová metoda - diskuse Vlastnosti: nem nná ást algoritmu je implementována pouze jednou, podt ídy implementují pro n specifické chování (statický vzor)
P íklad v J2SE: vlastní chování t íd java.lang.Thread i java.util.TimerTask se ur í implementací metody run() v jejich podt íd .
Související vzory: tovární metoda – zvláštní p ípad šablonové metody (tvorba objekt ) strategie (viz dále)
SWI041 - Návrhové vzory
71
Problém Je pot eba m nit chování objektu za b hu P íklady: r zné zp soby prezentace dat (nap . lámání textu, obarvování syntaxe v IDE) r zné zp soby interpretace dat (nap . kalendá )
SWI041 - Návrhové vzory
72
P íklad: výpis kalendá e kalendá se liší pro r zné národy a náboženství první den v týdnu m že být r zný množina svátk je odlišná pot ebujeme vypsat dny v týdnu s odlišením svátk
SWI041 - Návrhové vzory
73
Vzor Strategy (strategie) Aka policy/postup Motivace: pro n které innosti existuje mnoho algoritm , které ale nelze napevno implementovat (nap . jsou vhodné vždy jen pro ur itou situaci)
SWI041 - Návrhové vzory
74
Strategie
Obrázek p evzat z [GoF]
Vlastnosti (srv. šablonová metoda) pro stejná data se používají r zné algoritmy algoritmus je zapouzd ený do samostatného objektu algoritmus lze dynamicky m nit za b hu
SWI041 - Návrhové vzory
75
P íklad – strategie 1 Definujeme rozhraní CalendarPrinter, které bude ídit výpis kalendá e public interface CalendarPrinter { public int getFirstDayofWeek (); public boolean isHoliday (int day, int month); }
SWI041 - Návrhové vzory
76
P íklad – strategie 2 Vytvo íme t ídu Calendar s atributem printer a p íslušnými metodami set a get (setery a getery) public class Calendar { protected printer = new DefaultCalendarPrinter (); public void setPrinter (CalendarPrinter printer) { if (printer != null) { this.printer = printer; } } public CalendarPrinter getPrinter () { return printer; } }
SWI041 - Návrhové vzory
77
P íklad – strategie 3 P idáme metodu využívající služby objektu CalendarPrinter public void printWeek (int week) { int start = printer.getFirstDayofWeek (); for (...) { if (printer.isHoliday (day, month)) { //... } else { //... } } } SWI041 - Návrhové vzory
78
P íklad – strategie 4 Základní implementace CalendarPrinter public class DefaultCalendarPrinter implements CalendarPrinter { public int getFirstDayofWeek() { return 7; // nedele } public boolean isHoliday(int day, int month) { return false; // zadne svatky :-) } }
SWI041 - Návrhové vzory
79
P íklad – strategie 5 Nyní vytvo íme (nebo uživatelé našeho API) další implementace public class FrenchCalendarPrinter implements CalendarPrinter { public int getFirstDayofWeek() { return 1; // pondeli } public boolean isHoliday(int day, int month) { return day == 14 && month == 7; } } SWI041 - Návrhové vzory
80
Strategie - diskuse P íklady v J2SE: P i vytvá ení instancí java.util.TreeSet lze specifikovat objekt typu java.util.Comparator, který definuje zp sob uspo ádání množiny. P i vytvá ení instance t ídy java.lang.Thread lze specifikovat objekt typu java.lang.Runnable s definovanou metodou run() (srv. p edefinování metody run() v potomkovi t ídy Thread u šablonové metody). java.util.zip.CheckedInputStream
Související vzory: šablonová metoda – statická verze vzoru strategie
SWI041 - Návrhové vzory
81
Problém T ída má rozhraní pro tvorbu nových objekt . Konkrétní podt ídy pot ebují vytvá et velmi odlišné typy t chto objekt . Jak to ud lat, když t ída neví jaké objekty bude vytvá et?
SWI041 - Návrhové vzory
82
Factory Method/Tovární metoda Virtuální konstruktor Použití: editory vytvá ejí jednotným zp sobem r zné dokumenty (viz p íklad) abstraktní (logické) objekty poskytují r znou grafickou reprezentaci (delegáta)
SWI041 - Návrhové vzory
83
Factory Method/Tovární metoda
Tovární metoda createDocument v t íd Editor vytvá í r zné instance t ídy Document podle toho, na které podt íd je vyvolána. SWI041 - Návrhové vzory
84
Factory Method/Tovární metoda Vlastnost: poskytuje rozhraní pro tvorbu objekt , ale volbu vytvá eného objektu nechává na podt ídách
P íklad v J2SE: javax.swing.text.EditorKit.createDefaultDocument () Související vzory: šablonová metoda (viz dále) delegát (Abstract) Factory – samostatná t ída (typu singleton) ur ená pro tvorbu objekt
SWI041 - Návrhové vzory
85
Problém Na stavu jednoho objektu závisí ada jiných objekt . P i zm n stavu objektu pot ebují být závislé objekty automaticky vyrozum ni. Jak toho docílit?
SWI041 - Návrhové vzory
86
Observer/Pozorovatel Aka Dependents, Publish-Subscribe J2SE: Event Delegation Model
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
87
Observer/Pozorovatel Vlastnosti volné spojení t íd Observer a Subject hromadná komunikace (broadcast/vysílání) selektivní sledování zm n možnost odmítnutí zm n
P íklady v J2SE: java.awt.* java.awt.event.* Component ⇔ MouseListener JComponent ⇔ PropertyChangeListener SWI041 - Návrhové vzory
88
Problém Chceme použít n jakou užite nou t ídu, která ale má jiné rozhraní, než o ekáváme. Co s tím?
SWI041 - Návrhové vzory
89
Adapter/Adaptér wrapper/obal
Obrázek p evzat z [GoF]
SWI041 - Návrhové vzory
90
Adapter/Adaptér T ídní implementace: vícenásobná d di nost
Instan ní implementace: kompozice
Obrázky p evzaty z [GoF]
SWI041 - Návrhové vzory
91
Adapter/Adaptér P íklad v J2SE: java.awt.event.* MouseAdapter adaptér rozhraní MouseListener poskytuje „prázdné“ implementace všech metod MouseListener
Související vzory: delegát
SWI041 - Návrhové vzory
92
Problém Máme hierarchicky organizovaný celek s jehož ástmi chceme manipulovat jednotným zp sobem. Jak na to?
SWI041 - Návrhové vzory
93
Composite/Kompozice
Použití:
Obrázek p evzat z [GoF]
grafická uživatelská rozhraní strukturované dokumenty (XML, HTML,...) SWI041 - Návrhové stromov vzory 94 organizovaná data...
Composite/Kompozice Vlastnosti: definuje spole né rozhraní pro objekty stromové hierarchie jednoduché použití – klient se nestará, zda pracuje s celkem nebo ástí snadné rozši ování – nové prvky automaticky fungují se starými klienty
P íklad v J2SE: java.awt.* Component – abstraktní komponenta Container – abstraktní kontejner Button, Label – konkrétní jednoduché objekty Panel, Window – konkrétní složené objekty
SWI041 - Návrhové vzory
95
The End