PŘÍRODOVĚDECKÁ FAKULTA UNIVERZITY PALACKÉHO KATEDRA INFORMATIKY
BAKALÁŘSKÁ PRÁCE
Návrhové vzory
2013
Dan Doležel
Anotace Návrhové vzory jsou doporučené postupy pro řešení často se vyskytujících úloh. V úvodu jsou shrnuté pojmy související s problematikou návrhových vzorů a jejich stručný popis. Dále v textu následuje rozdělení návrhových vzorů do skupin a podrobný popis vybraných zástupců z každé skupiny. Součásti práce je aplikace, která umožňuje editovat UML diagram tříd s využitím návrhových vzorů. Hotový diagram je možné exportovat do zdrojových kódů jazyka C++. Klíčová slova: Návrhový vzor, UML diagram, třída.
Poděkování: Děkuji vedoucímu bakalářské práce RNDr. Arnoštu Večerkovi za cenné rady, věcné připomínky a vstřícnost při konzultacích a vypracování bakalářské práce.
Obsah 1. Úvod
7
2. Návrhové vzory 2.1. Definice pojmů . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2. Stručná historie návrhových vzorů . . . . . . . . . . . . . . . . . . 2.3. Použití návrhových vzorů v praxi . . . . . . . . . . . . . . . . . .
8 8 8 8
3. Vybrané návrhové vzory 3.1. Návrhové vzory vytváření . . . . . . . . . . . . . . . 3.1.1. Abstraktní továrna (Abstract Factory) . . . . 3.1.2. Stavitel (Builder) . . . . . . . . . . . . . . . . 3.1.3. Tovární metoda (Factory method) . . . . . . . 3.1.4. Další návrhové vzory vytváření . . . . . . . . 3.2. Strukturální návrhové vzory . . . . . . . . . . . . . . 3.2.1. Adaptér (Adapter) . . . . . . . . . . . . . . . 3.2.2. Most (Bridge) . . . . . . . . . . . . . . . . . . 3.2.3. Dekorátor (Decorator) . . . . . . . . . . . . . 3.2.4. Další strukturální návrhové vzory . . . . . . . 3.3. Návrhové vzory chování . . . . . . . . . . . . . . . . 3.3.1. Řetěz odpovědnosti (Chain of Responsibility) 3.3.2. Příkaz (Command) . . . . . . . . . . . . . . . 3.3.3. Iterátor (Iterator) . . . . . . . . . . . . . . . . 3.3.4. Další návrhové vzory chování . . . . . . . . . 4. Editor UML 4.1. Analýza . . . . . . . . . . . . . . . 4.2. Struktura kódu . . . . . . . . . . . 4.2.1. Základní framework aplikace 4.2.2. Prvky UML diagramu . . . 4.2.3. Uživatelské rozhraní . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . . .
10 10 10 11 12 13 14 14 15 16 17 18 18 19 20 21
. . . . .
23 23 23 23 23 24
Závěr
25
Reference
26
A. Uživatelská dokumentace k UML editoru A.1. Hlavní okno programu . . . . . . . . . . . . . . . . . . . . . . . . A.2. Položky hlavního menu . . . . . . . . . . . . . . . . . . . . . . . . A.3. Editace diagramu . . . . . . . . . . . . . . . . . . . . . . . . . . .
27 27 27 28
4
B. Možnosti rozšíření aplikace UML editoru B.1. Rozšíření stávající aplikace . . . . . . . . . . . . . . . . . . . . . . B.2. Návrh nové aplikace . . . . . . . . . . . . . . . . . . . . . . . . .
30 30 30
C. Obsah přiloženého CD
31
5
Seznam obrázků 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
UML diagram: Abstraktní továrna. . . UML diagram: Stavitel. . . . . . . . . UML diagram: Tovární metoda. . . . . UML diagram: Prototyp. . . . . . . . . UML diagram: Jedináček. . . . . . . . UML diagram: Adaptér. . . . . . . . . UML diagram: Most. . . . . . . . . . . UML diagram: Dekorátor. . . . . . . . UML diagram: Strom. . . . . . . . . . UML diagram: Muší váha. . . . . . . . UML diagram: Zástupce. . . . . . . . . UML diagram: Řetěz odpovědnosti. . . UML diagram: Příkaz. . . . . . . . . . UML diagram: Iterátor. . . . . . . . . UML diagram: Interpret. . . . . . . . . UML diagram: Prostředník. . . . . . . UML diagram: Třídy aplikace pro práci Hlavní okno aplikace. . . . . . . . . . .
6
. . . . . . . . . . . . . . . . s .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . UML diagramem. . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
11 12 13 13 14 15 15 16 17 18 18 19 19 20 21 22 24 27
1.
Úvod
V bakalářské práci se budu zabývat problematikou návrhových vzorů. Návrhové vzory (anglicky design patterns) jsou doporučené postupy pro řešení často se vyskytujících úloh. V softwarovém inženýrství jsou využívány pro zefektivnění návrhu počítačových programů a zjednodušení jejich implementace. Jejích použití při návrhu aplikací umožňují editory pro návrh tříd a vazeb mezi nimi. Vznik pojmu návrhových vzorů se původně pojí s oblasti architektury v polovině dvacátého století. Do oblasti výpočetní techniky tento termín proniká v devadesátých letech dvacátého století spolu s větším rozšířením objektově orientovaného přístupu k programování. Jednotlivé návrhové vzory jsou dnes v podobě katalogů návrhových vzorů nedílnou součásti při návrhu programů. V teoretické části se zaměřím na existující návrhové vzory, jejich rozdělení, výhody použití a z každé skupiny detailně popíši několik zástupců. Při studiu dané problematiky jsem čerpal informace převážně ze zdrojů uvedených v sekci reference. Součástí bakalářské práce je vytvoření aplikace, která umožní navrhnout třídy a vazby mezi nimi s pomocí návrhových vzorů vytváření, strukturálních návrhových vzorů a návrhových vzorů chování. Z vytvořeného návrhu bude možné vyexportovat třídy do zdrojového kódu ve zvoleném programovacím jazyce podporujícího objektově orientované programování.
7
2. 2.1.
Návrhové vzory Definice pojmů
Návrhové vzory (anglicky design patterns) jsou doporučené postupy pro řešení často se vyskytujících úloh. V softwarovém inženýrství jsou využívány při návrhu počítačových programů. Návrhový vzor není knihovnou nebo částí zdrojového kódu, která by se přímo vkládala do vytvářených zdrojových kódů nebo se s nimi kompilovala. Jedná se o popis řešení problému, který může být aplikován na konkrétní situaci. V objektově orientovaném programování se používají objektově orientované návrhové vzory. Ty definují vztahy a interakce mezi třídami a objekty bez toho, aby určovaly konkrétní implementaci tříd. Tato práce se věnuje právě objektově orientovaným návrhovým vzorům. Pro zápis objektově orientovaných návrhových vzorů se nejčastěji používá UML diagramy. Ty umožňují na dostatečně obecné úrovni definovat třídy a vztahy mezi nimi. Jazyk UML (z anglického Unified Modeling Language) se skládá z grafických prvků, které je možné v souladu s pravidly jazyka vzájemně kombinovat do diagramů. Jazyk UML definuje 13 diagramů. Pro potřeby této práce bude využíván pouze diagram tříd.
2.2.
Stručná historie návrhových vzorů
Vznik pojmu ”návrhový vzor” se datuje do šedesátých let dvacátého století, kdy se tento termín poprvé objevuje v architektuře. V oblasti výpočetní techniky se o návrhových vzorech začína mluvit na konferenci OOPSLA v roce 1987 v Orlandu. Základním kamenem pro použití návrhových vzorů se stala kniha Design Patterns: Elements of Reusable Object-Oriented Software od autorů Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides [1]. Poprvé byla vydána v roce 1995 a dodnes je považována za pomyslnou ”bibli návrhových vzorů”. Čtveřice autorů se stala známá jako GoF (Gang of Four - banda čtyř) a tato zkratka se často vyskytuje i v odborných textech.
2.3.
Použití návrhových vzorů v praxi
Sbírky návrhových vzorů jsou označovány jako katalogy návrhových vzorů. Nejznámější z nich je GoF [1]. V praxi se vyskytují jako součásti programovacích jazyků (například šablony v knihovně STL jazyka C++), které je možné přímo využívat při psaní kódu. Další možnosti jsou šablony v UML editorech, které se využívají při návrhů diagramů tříd.
8
Použití návrhových vzorů podstatně zrychluje a zlevňuje vývoj aplikací. Mezi hlavní výhody, které přináší, patří: • Zrychlení vývoje - není potřeba znovu vymýšlet něco, co už funguje. • Menší chybovost - navrhované postupy jsou ověřeny praxi. • Rozšiřitelnost - návrhové vzory počítají s možností rozšíření do budoucna. Nebude potřeba přepisovat tolik kódu. • Psaní méně kódu - vazby mezi třídami je možné vyexportovat z UML diagramu do zdrojových kódů. Některé programovací jazyky nabízejí šablony, které je možné přímo použít. • Standardizace postupů - lepší čitelnost zdrojových kódů ostatními členy týmu.
9
3.
Vybrané návrhové vzory
Návrhové vzory je možné rozdělit do skupin podle použití. Kniha GoF [1] definuje 23 návrhových vzorů rozdělených do tří skupin: návrhové vzory vytváření, strukturální návrhové vzory a návrhové vzory chování. Tyto vzory jsou považovány za obecně použitelné, proto se v následujícím textu tohoto rozdělení budu držet. Kromě výše zmíněného je rozšířeno a využívá se velké množství dalších návrhových vzorů. Tyto vzory jsou ale často úzce specializované pro specifické oblasti programování. Jako příklad uvedu skupinu návrhových vzorů, které řeší problematiku souběžně běžících úloh (concurrency patterns). Ve zbytku kapitoly je uvedeno několik zástupců pro každou skupinu návrhových vzorů. Při psaní tohoto přehledu jsem vycházel z GoF [1], Návrhové vzory [3] a informaci na internetu [4]. Veškeré UML diagramy, nebude-li uvedeno jinak, jsem vytvořil v UML editoru, který je součástí této bakalářské práce.
3.1.
Návrhové vzory vytváření
Tato skupina návrhových vzorů řeší problémy související s vytvářením objektů. Snahou těchto návrhových vzorů je popsat postup výběru třídy nového objektu a zajištění správného počtu jeho instancí. Většinou se to řeší dynamickým rozhodováním za běhu programu. 3.1.1.
Abstraktní továrna (Abstract Factory)
Tento návrhový vzor poskytuje možnost obalit skupinu individuálních konkrétních továren tykajících se společného tématu. Obvyklé použití vzoru spočívá ve vytvoření konkrétní implementace abstraktní továrny, která je odpovědná za výrobu potřebných objektů. Klient se nestará o to, které konkrétní objekty vyrábí která konkrétní továrna, protože používá jednotné rozhraní abstraktní továrny. Vzor odděluje detaily implementace skupiny objektů od jejich obecného používání. Příslušný UML diagram je znázorněn na obrázku 1.
10
Obrázek 1. UML diagram: Abstraktní továrna. Význam jednotlivých tříd v diagramu: • AbstractFactory: deklaruje rozhraní pro operace vytváření abstraktních produktů. • ConcreteFactory: implementuje operace pro vytváření konkrétních instancí produktů. • ProductX, ProductY : deklaruje rozhraní pro jednotlivé typy produktů. • ProductX1, ProductX2 : definuje objekty produktů zděděných z abstraktní třídy ProduktX. • ProductY1, ProductY2 : definuje objekty produktů zděděných z abstraktní třídy ProduktY. 3.1.2.
Stavitel (Builder)
Stavitel slouží k abstrahování tvorby složitých objektů. Je navržen tak, aby stejné výrobní schéma mohlo být použito pro tvorbu různých objektů. Způsob konstrukce těchto objektů je tedy stejný, jednotlivé kroky se však liší. Často se 11
používá společně s návrhovým vzorem Kompozit (Composite), konkrétně vytvářené objekty mohou být typu kompozit, dle zmíněného vzoru. Příslušný UML diagram je znázorněn na obrázku 2.
Obrázek 2. UML diagram: Stavitel. Význam jednotlivých tříd v diagramu: • Director : je třída, která řídí proces vytváření objektů. Instance třídy Director získává od klienta informaci, který Builder má použít. Tím je i definováno, který produkt bude vyráběn. Director řídí vytvoření produktu voláním metod pro vytvoření jednotlivých částí z rozhraní Builder. Po vytvoření požadované části výsledného produktu je tato do něho začleněna. Director je odstíněn od způsobu, jakým se vytvářejí konkrétní části a jak se skládají. Určuje ovšem, kdy se mají části vyrobit, a tím řídí proces vytváření produktů. • Builder : je abstraktní rozhraní pro tvorbu objektů typu Product. Metoda BuildPart() slouží k vytvoření konkrétní části objektu, o její volání se stará Director. • ConcreteBuilder : je implementace rozhraní Builder schopná vytvářet další objekty. Vytváří a sestavuje součásti pro tvorbu složitých objektů. Metoda GetResult() slouží k předání výsledného produktu a volá ji zpravidla klient, který konstrukci objektu vyvolal. • Product: reprezentuje produkt po jeho celkovém sestavení. ConcreteBuilder vytváří interní reprezentaci produktu a definuje procesy jeho vytváření. 3.1.3.
Tovární metoda (Factory method)
Jako tovární metoda se označuje metoda, která vytváří a vrací novou instanci požadovaného objektu. Typ objektu a popřípadě i jeho počáteční vlastnosti jsou dané předanými parametry tovární metodě. Příslušný UML diagram je znázorněn na obrázku 3. 12
Obrázek 3. UML diagram: Tovární metoda. Význam jednotlivých tříd v diagramu: • Product: definuje rozhraní objektů, které vytváří tovární metoda. • ConcreteProduct: implementuje rozhraní bázové třídy Product pro konkrétní typy objektů. • Creator : deklaruje tovární metodu FactoryMethod(), která vrací objekt zděděný z bázové třídy Product. Může také definovat výchozí implementaci tovární metody, která vrací výchozí typ ConcreteProduct. • ConcreteCreator : přetěžuje tovární metodu FactoryMethod() a vrací odpovídající instanci ConcreteProduct. 3.1.4.
Další návrhové vzory vytváření
Další návrhové vzory vytváření podle GoF [1] budou popsány pouze ve stručnosti. Jsou to:
Obrázek 4. UML diagram: Prototyp.
13
• Prototyp (Prototype) : Používá se v případech, když je vytváření třídy časově náročné. V případě požadavku na vytváření mnoha instanci dané třídy je výhodnější vytvořit pouze jednu a ostatní z ní naklonovat. Při klonování jde většinou o mělkou kopii (kopírují se pouze reference a ne celé objekty). Příslušný UML diagram je znázorněn na obrázku 4. • Jedináček (Singleton) : zabezpečuje, že v celém programu bude existovat pouze jediná instance dané třídy. Zároveň také k této třídě poskytuje globální přístup. Jako příklad využití můžeme uvést schránku v systému Windows. Příslušný UML diagram je znázorněn na obrázku 5.
Obrázek 5. UML diagram: Jedináček.
3.2.
Strukturální návrhové vzory
Strukturální návrhové vzory se zaměřují na možnosti uspořádání jednotlivých tříd nebo komponent v systému. Snahou je zpřehlednit systém a využít možnosti strukturalizace kódu. 3.2.1.
Adaptér (Adapter)
Tento návrhový vzor se využije tam, kde je potřeba z nějakého důvodu změnit rozhraní třídy. Mezi ní a jejího uživatele vložíme třídu adaptéru, která bude zabezpečovat konverzi rozhraní třídy na požadované rozhraní. Typické využití je při použití hotového kódu s nekompatibilním rozhraním. V jazyce Java jsou adaptéry použité pro obalení primitivních datových typů. Často jsou označované jako wrapper. Příslušný UML diagram je znázorněn na obrázku 6. Význam jednotlivých tříd v diagramu: • Target: třída obsahující požadované rozhraní. • Adapter : třída adaptéru, která převádí specifické rozhraní třídy Adaptee na požadované třídou Target. • Adaptee: definuje stávající rozhraní, který je potřeba přizpůsobit • Client: využívá objekty s použitím rozhraní třídy Target. 14
Obrázek 6. UML diagram: Adaptér.
3.2.2.
Most (Bridge)
Tento návrhový vzor odděluje abstrakci od implementace, takže obě lze měnit nezávisle na sobě. Klient komunikuje přes rozhraní abstrakce, která zprostředkovává funkcionalitu implementace. Tento přístup je výhodný například při vytváření programů běžících na různých systémech. Program využívá rozhraní abstrakce, zatímco implementace se liší na každé platformě. Příslušný UML diagram je znázorněn na obrázku 7.
Obrázek 7. UML diagram: Most.
15
Význam jednotlivých tříd v diagramu: • Abstraction: definuje abstraktní rozhraní a udržuje referenci na objekt typu Implementor. • RefinedAbstraction: rozšiřuje rozhraní definované třídou Abstraction. • Implementor : definuje rozhraní implementačních tříd. Toto rozhraní nemusí přesně odpovídat rozhraní třídy Abstraction. Velmi často toto rozhraní obsahují základní operace a rozhraní třídy Abstraction na jejich základě definuje složitější operace. • ConcreteImplementor : implementuje rozhraní třídy Implementor pro konkrétní implementaci. 3.2.3.
Dekorátor (Decorator)
Tento návrhový vzor umožňuje přidat další přídavnou funkcionalitu k objektu tak, že objekt zabalí do jiného objektu, který má na starosti pouze tuto přidanou funkcionalitu. Zbytek požadavků je delegován dále na zabalený objekt. Dekorátor poskytuje flexibilní alternativu k dědění a umožňuje přidávat funkčnost dynamicky. Příslušný UML diagram je znázorněn na obrázku 8.
Obrázek 8. UML diagram: Dekorátor. Význam jednotlivých tříd v diagramu: • Component: definuje rozhraní pro objekt, který může svou funkcionalitu rozšiřovat dynamicky.
16
• ConcreteComponent: definuje objekt, ke kterému může být přidána rozšiřující funkcionalita. • Decorator : udržuje referenci na objekt Component a definuje rozhraní, které vyhovuje třídě Component. • ConcreteDecorator : přidává funkcionalitu pro třídu Component. 3.2.4.
Další strukturální návrhové vzory
Další strukturální návrhové vzory podle GoF [1] budou popsány pouze ve stručnosti. Jsou to:
Obrázek 9. UML diagram: Strom. • Strom (Composite) : umožňuje uspořádat jednoduché a z nich složené objekty (kompozitní) tak, aby k oběma typům objektů bylo možné přistupovat jednotným způsobem. Příslušný UML diagram je znázorněn na obrázku 9. • Fasáda (Facade) : vytváří jednotné rozhraní k množině rozhraní v subsystému. Tím definuje jednotné rozhraní vyšší úrovně, které usnadňuje používáni subsystému. • Muší váha (Flyweight) : Pomocí sdílení umožňuje podporu velkého množství malých objektů. Příslušný UML diagram je znázorněn na obrázku 10. • Zástupce (Proxy) : odstiňuje uživatele od objektu, který zastupuje. Díky tomu dokáže řídit přístup uživatelů k danému objektu. Příslušný UML diagram je znázorněn na obrázku 11.
17
Obrázek 10. UML diagram: Muší váha.
Obrázek 11. UML diagram: Zástupce.
3.3.
Návrhové vzory chování
Tato skupina návrhových vzorů se stará o chování systému. Mohou být založeny na třídách nebo objektech. U tříd využívají při návrhu řešení především principu dědičnosti. V druhém přístupu je řešena spolupráce mezi objekty a skupinami objektů, která zajišťuje dosažení požadovaného výsledku. 3.3.1.
Řetěz odpovědnosti (Chain of Responsibility)
Umožňuje, aby požadavek zpracoval jiný objekt než ten, kterému byl zaslán. Předpokládá se, že objekty budou zřetězeny tak, aby objekt, který není schopen zpracovat požadavek, ho mohl předat dalšímu objektu. Příslušný UML diagram je znázorněn na obrázku 12. 18
Obrázek 12. UML diagram: Řetěz odpovědnosti. Význam jednotlivých tříd v diagramu: • Handler : implementuje rozhraní pro ošetření požadavků. • ConcreteHandler : zpracovává konkrétní požadavek. • Client: zadává požadavek do řetězu. 3.3.2.
Příkaz (Command)
Umožňuje zabalit metodu do objektu a dále s ní pracovat jako s běžným objektem. Tento přístup dovoluje dynamickou výměnu používaných metod za běhu programu a přizpůsobení programu potřebám uživatele. Příslušný UML diagram je znázorněn na obrázku 13.
Obrázek 13. UML diagram: Příkaz.
19
Význam jednotlivých tříd v diagramu: • Command : deklaruje rozhraní pro volání operací. • ConcreteCommand : implementuje příslušnou operací. • Client: vytváří instanci třídy ConcreteCommand a nastavuje ji třídě Receiver. • Receiver : spouští příslušnou operací třídy ConcreteCommand pro zpracování požadaveku. 3.3.3.
Iterátor (Iterator)
Skrývá před klientem vnitřní implementaci uložení dat v kontejneru a poskytuje sekvenční přístup k těmto datům. Vnitřní implementace bývá často nelineární (například stromová struktura). Příslušný UML diagram je znázorněn na obrázku 14.
Obrázek 14. UML diagram: Iterátor. Význam jednotlivých tříd v diagramu: • Iterator : definuje rozhraní pro přístup k elementům. • ConcreteIterator : implementuje rozhraní třídy Iterator. Udržuje potřebné informace procházení kontejneru. • Aggregate: definuje rozhraní pro vytváření objektů iterátorů. • ConcreteAggregate: vytváří odpovídající iterátor pro třídu ConcreteIterator.
20
3.3.4.
Další návrhové vzory chování
Další návrhové vzory chování podle GoF [1] budou popsány pouze ve stručnosti. Jsou to:
Obrázek 15. UML diagram: Interpret.
• Interpret (Interpreter): Definuje reprezentaci gramatických pravidel jazyka pomocí tříd. Zároveň definuje interpret tohoto jazyka za pomocí metod instancí takto navrhnutých tříd. Příslušný UML diagram je znázorněn na obrázku 15. • Prostředník (Mediator): Umožňuje odstranit vazby navzájem komunikujících objektů tím, že mezi komunikující objekty vloží objekt prostředníka. Tím zruší přímou závislost mezi původními objekty a dovolí je upravovat nezávisle na sobě. Příslušný UML diagram je znázorněn na obrázku 16. • Pamětník (Memento): Uchovává stav objektů bez narušení jejich zapouzdření. To umožňuje pozdější návrat objektů do dříve uloženého stavu. • Pozorovatel (Observer): Zavádí vztah mezi objekty pozorovatelů a pozorovaných. Pokud pozorovaný objekt změní svůj stav, jsou na to upozorněni všichni pozorovatelé daného objektu. • Stav (State): umožňuje objektu měnit své chování při změně vnitřního stavu. Objekt se pak tváří, jako by měnil svoji třídu. • Strategie (Strategy): definuje množinu objektů reprezentujících algoritmy řešící zadanou úlohu (objekty mají stejné rozhraní) a umožní se mezi nimi dynamicky přepínat. 21
• Šablonová metoda (Template method): definuje kostru algoritmu, z něhož některé části deleguje na své podtřídy. Tím je zaručeno, že ne všechny kroky algoritmu musí být známy při vzniku šablony. • Návštěvník (Visitor): definuje nové operace pro skupinu tříd, aniž by bylo nutno měnit kód těchto tříd.
Obrázek 16. UML diagram: Prostředník.
22
4.
Editor UML
Mezi vytyčené cíle patří tvorba editoru UML diagramů s podporou návrhových vzorů představených v předchozí kapitole. Tato část se věnuje implementačním detailům. Informace o jazyku UML jsem čerpal převážně z The unified modeling language reference manual od autorů James Rumbaugh, Ivar Jacobson, and Grady Booch[2].
4.1.
Analýza
Jazyk UML definuje 13 typů diagramů. Pro potřeby této práce postačuje diagram tříd. Případné rozšíření programu o další typy UML diagramu bude nastíněno v příloze B - Možnosti rozšíření aplikace UML editoru. Protože v zadání nejsou specifikované implementační požadavky, zvolil jsem za operační systém Microsoft Windows XP nebo novější verzi. Aplikace bude napsána v jazyce C++ a tento jazyk bude také použit pro export navržených diagramů do zdrojových kódů.
4.2.
Struktura kódu
Zdrojové kódy jsou rozděleny do tří sekcí (základní Framework aplikace, prvky UML diagramu a uživatelské rozhraní). Pokud mezi jednotlivými sekcemi existuje závislost, je vždy jednostranná. V případě potřeby oboustranné komunikace je použit komunikační interface, který odděluje implementace. Toto řešení je zvoleno pro snadnější možnost výměny jednotlivých částí. 4.2.1.
Základní framework aplikace
Tato část je odpovědna za inicializaci a deinicializaci aplikace a o pravidelné updatovaní potřebných částí. 4.2.2.
Prvky UML diagramu
Pro modelování tříd a vazeb mezi nimi je potřeba implementovat prvky diagramu tříd podle definice UML diagramu. Pro jednoduchou práci s objekty diagramu mají všechny společnou bázovou třídu C ItemBase, která definuje rozhraní pro práci s nimi (vytvoření, smazání, editace, ukládání, načítání a export). Třída C Diagram uchovává všechny entity v editovaném diagramu. Tyto vztahy znázorňuje obrázek 17.
23
Obrázek 17. UML diagram: Třídy aplikace pro práci s UML diagramem.
4.2.3.
Uživatelské rozhraní
Tato část je odpovědná za zobrazení grafiky hry a za komunikaci s uživatelem. Je založena na Windows API. Pro práci s dialogy je definována bázová třída C BaseDialog, která zastřešuje komunikaci dialogů se systémem.
24
Závěr V teoretické části jsem se zaměřil především na návrhové vzory definované v katalogu [1], který je obecně považovaný za základní seznam. Obsahuje 23 návrhových vzorů rozdělených do tří skupin. Z každé skupiny jsem vybral a podrobně popsal několik zástupců. Mnohé z nich řeší obsáhlé problémy a je z nich patrné, že jejich znalost a použití při návrhu aplikací podstatným způsobem zefektivní proces návrhu. Mezi výhody použití návrhových vzorů patří zrychlení vývoje, menší chybovost a budoucí rozšiřitelnost. Z historie návrhových vzorů je patrné, že s rozšířením objektově orientovaného přístupu k programování získalo jejich využití při návrhu aplikací na důležitosti. V praktické části bakalářské práce jsem vytvořil aplikaci, která umožňuje definovat třídy a vazby mezi nimi. K tomu využívá připravené šablony s návrhovými vzory popsanými v teoretické části. Takto vytvořené diagramy je možné ukládat a načítat, vytvářet nové šablony návrhových vzorů a exportovat diagramy do zdrojového kódu jazyka C++. Tato aplikace je schopna editovat v souladu se standardy jazyka UML pouze diagram tříd. Z popsaných návrhových vzorů je v kódech aplikace nejčastěji používán iterátor. Největší část vývoje aplikace mi zabralo uživatelské rozhraní. Pro implementaci této části by byl vhodnější jazyk C#, který v této oblasti poskytuje lepší nástroje. Vzhledem k tomu, že i zbytek aplikace není výpočetně náročný, nebyl by problém použít jazyk C# pro tvorbu celé aplikace. Další možnosti rozšíření aplikace jsou popsány v příloze 2 - Možnosti rozšíření aplikace UML editoru.
25
Reference [1] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley, 1995. ISBN: 0201633612 [2] James Rumbaugh, Ivar Jacobson, and Grady Booch. The unified modeling language reference manual. Addison-Wesley, 2004. ISBN: 0-321-24562-8 [3] Rudolf Pecinovský. Návrhové vzory. Computer Press a.s., 2007. ISBN 97880-251-1582-4 [4] Dofactory. Design patterns. Elektronický dokument.
26
A. A.1.
Uživatelská dokumentace k UML editoru Hlavní okno programu
Hlavní okno programu zobrazuje diagram a pomocí akcí myši nebo nabídky menu umožňuje jeho editaci. Hlavní okno znázorňuje obrázek 18.
Obrázek 18. Hlavní okno aplikace. Skládá se z následujících části: • Lišta hlavního menu. • Lišta nástrojů. • Hlavní část okna zobrazuje editovaný diagram. • Posuvníky vpravo a dole slouží pro posun pracovní plochy.
A.2.
Položky hlavního menu
Veškerá funkcionalita aplikace je dostupbná z hlavního menu. Položky jsou rozdělěny do tří podmenu a mají následující význam: 27
Podmenu Soubor • Nový - smaže diagram a začne editaci nového • Otevřít - načte dříve uložený diagram • Uložit - uloží editovaný diagram • Uložit jako. . . - uloží editovaný diagram do zadaného souboru • Konec - ukončí program Podmenu Diagram • Vložit třídu - vloží do diagramu novou třídu • Vložit poznámku - vloží do diagramu novou poznámku • Vložit vazbu mezi třídami - vloží do diagramu novou vazbu mezi dvěma právě označeními třídami. Pokud nebudou označeny dvě třídy, upozorní na to dialogem. • Vložit návrhový vzor - vloží do diagramu předem uložený návrhový vzor • Editovat označenou položku - spustí dialog s nastavením vlastnosti příslušný k označené položce • Smazat označené položky - smaže položky, které jsou označené • Exportovat do C++ - spustí dialog s výběrem lokace pro uložení a exportuje editovaný diagram do příslušných zdrojových kód Podmenu Nápověda • Zobrazit nápovědu - zobrazí nápovědu pro ovládání programu • O aplikaci - about dialog
A.3.
Editace diagramu
• Kliknutím levého tlačítka myši se označí objekt pod kurzorem. Pokud tam žádný není, selekce se vynuluje. • Pokud při kliku levým, tlačítkem myši bude stištěná zároveň i klávesa Ctrl, selekce se bude přepínat označen/neoznačen.
28
• Kliknutím levého tlačítka myši nad objektem a pohybem myši dojde k posunu objektu na ploše. Pokud je označených více objektů, budou se přesouvat všechny. Přesun nefunguje na vazby mezi třídami, jejich pozice se počítá z pozic tříd, které spojuje. • Dvojklikem levého tlačítka myši se spustí dialog s editací vlastnosti objektu pod kurzorem. • Označené objekty jsou červeně orámovány. • Všechny nově vytvářené objekty (třídy, poznámky i celé návrhové vzory) se umístí v levém horním rohu, odkud je možné je podle potřeby přesunout. • Při vyplňování vlastnosti objektů bude uživatel upozorněn dialogem na nevalidní data.
29
B. B.1.
Možnosti rozšíření aplikace UML editoru Rozšíření stávající aplikace
• undo/redo • copy/paste • tisk diagramu • export diagramu do grafického formátu • speciální dialog pro výběr návrhového vzoru: měl by se zobrazovat náhled • lepší podpora práce s myší: selekce výběrem oblasti, posun pracovní plochy i tažením kurzoru myši bez označeného objektu, více podporovat akci drag&drop • zoom • u vazeb mezi třídami přidat možnost editovat tvar čáry
B.2.
Návrh nové aplikace
Aplikaci bych navrhl jako modulární stavebnici. Základem by byl program, který by pouze definoval rozhraní pro moduly a bázové třídy (například pro objekty diagramu). Veškerá funkcionalita by se nacházela v modulech, které by byly obsaženy v DLL souborech. Tím by byla zajištěna budoucí rozšiřitelnost bez nutnosti měnit program. Uživatelské rozhraní by mohlo být také součásti modulů, což by umožňovalo jeho výměnu. Kromě změn popsaných v sekci B.1. by nebyl problém rozšířit program o: • nové typy UML diagramů • nové uživatelské rozhraní (například pro integraci do MS Visual Studia) • export diagramu do dalších programovacích jazyků Vzhledem k tomu, že samotný program bez modulů by byl k ničemu, základní moduly dodávané s programem by byly označeny jako systémové a jejich přítomnost by byla vyžadována.
30
C.
Obsah přiloženého CD
bin/ Obsahuje spustitelný soubor UML Editor.exe. Program nevyžaduje instalaci. V podadresářích se nachází soubory s nápovědou a předdefinovanými návrhovými vzory. doc/ Dokumentace práce ve formátu PDF, vytvořená dle závazného stylu KI PřF pro diplomové práce, včetně všech příloh, a všechny soubory nutné pro bezproblémové vygenerování PDF souboru dokumentace (v ZIP archivu), tj. zdrojový text dokumentace, vložené obrázky, apod. src/ Kompletní zdrojové texty programu UML Editor se všemi potřebnými (převzatými) zdrojovými texty, knihovnami a dalšími soubory pro bezproblémové vytvoření spustitelných verzí programu. readme.txt Instrukce pro instalaci a spuštění programu UML Editor, včetně požadavků pro jeho provoz. U veškerých odjinud převzatých materiálů obsažených na CD/DVD jejich zahrnutí dovolují podmínky pro jejich šíření nebo přiložený souhlas držitele copyrightu. Pro materiály, u kterých toto není splněno, je uveden jejich zdroj (webová adresa) v textu dokumentace práce nebo v souboru readme.txt.
31