1. prosince 2013, Brno Připravil: David Procházka Návrhové vzory: vyrábíme objekty Základy objektového návrhu
Co jsou to návrhové vzory Strana 2 / 28 Obsah přednášky 1 Co jsou to návrhové vzory 2 Továrny 3 Samotáři 4 Stavitelé 5 Shrnutí
Co jsou to návrhové vzory Strana 3 / 28 Návrhové vzory Design Patterns Návrhové vzory můžeme s nadsázkou označit za fintu, jak řešit určitý problém. Existuje 23 základních vzorů, od kterých se odvozují další. NV byly poprvé popsány v knize Gama, Helm, Johnson, Vlissides: Design Patterns (Gang of Four) Vzorem může být jakékoliv řešení problému.
Co jsou to návrhové vzory Strana 4 / 28 Rozdělení návrhových vzorů 1 Tvořivé vzory: Řeší problémy okolo vytváření objektů jak zajistit správný počet instancí, výběr vhodné třídy nového objektu atp. 2 Strukturální změny: Snahou je zpřehlednit, resp. vhodně strukturovat systém. Zabývají se uspořádáním a propojením objektů. 3 Vzory chování: Zapouzdřují určité procesy prováděné v systému. Např. jak zajistit spolupráci několika tříd při řešení problému.
Co jsou to návrhové vzory Strana 5 / 28 Vzory spolu souvisí Převzato z: http://www.stickyminds.com/
Co jsou to návrhové vzory Strana 6 / 28 Příklad finty: Přepravka Prvním jednoduchým nástrojem je přepravka. Jedná se o konteiner, který je předáván metodám a ty do něj umist ují data. Výhodou je, že metody si nemusí předávat data navzájem velké množství parametrů, ale jen jednu přepravku. Změnou obsahu přepravky nedojde ke změně rozhraní metody (řešení odolné vůči změnám).
Co jsou to návrhové vzory Strana 7 / 28 Přepravka: implementace 1 struct Pozice { 2 int x; 3 int y; 4 }; 5 6 struct Rozmer { 7 int sirka ; 8 int vyska ; 9 };
Co jsou to návrhové vzory Strana 8 / 28 Komentář implementace struct je totéž co class, jen je výchozí viditelnost public. 1 Atributy mohou být veřejné, ale je nutné, aby je někdo hlídal! Není dobré recyklovat přepravky (použiji Pozici místo Rozměru), Přepravka může být pro přenos mezi metodami nebo interní pro uchování skupiny hodnot pohromadě. 1 Používá se když jedná o podobnou třídu, která z principu použití nekontroluje svoje hodnoty
Továrny Strana 9 / 28 Obsah přednášky 1 Co jsou to návrhové vzory 2 Továrny 3 Samotáři 4 Stavitelé 5 Shrnutí
Továrny Strana 10 / 28 Tovární metoda Nahrazuje volání konstruktoru. Problém: Chci vracet různé objekty nebo před samotným vytvořením objektu potřebuji udělat nějakou činnost. 2 Řešení: Zapouzdřím vytváření objektů do speciální tovární metody. Pokud budu potřebovat instanci dané třídy, pouze zavolám metodu a ta mi instanci vrátí. Co jsem získal: Třída vůbec znát instanci toho, co si nechá vytvořit. Tj. není nutné incudovat hlavičkové soubory vytvářených tříd. Mám proces vytváření pod kontrolou na jediném místě. 2 Existuje řada dalších důvodů.
Továrny Strana 11 / 28 Tovární metoda Obtížnost hry Zajistěte, aby si uživatel mohl na počátku hry zvolit obtížnost. Na základě této obtížnosti jsou generovány ve hře různě silné instance třídy Mutant.
Továrny Strana 12 / 28 Tovární metoda: komplexní varianta Visual Paradigm for UML Standard Edition(Faculty of Business and Economics, Mendel University of Agriculture and Fo Mutant +getutok() : int +getmutant(level : int) : Mutant * #Mutant() +~Mutant() SilnyMutant #m_sila : int #m_jedovatost : int +SilnyMutant(sila : int, jedovatost : int) +getutok() : int SlabyMutant #m_sila : int +SlabyMutant(sila : int) +getutok() : int
Továrny Strana 13 / 28 Abstraktní továrna Obtížnost hry Zajistěte, aby si uživatel mohl na počátku hry zvolit obtížnost. Na základě této obtížnosti jsou generovány ve hře různě silné instance tříd Mutant, Skeleton atp.
Továrny Strana 14 / 28 Abstraktní továrna: příklad Visual Paradigm for UML Standard Edition(Faculty of Business and Economics, Mendel University of Agriculture and Forestry in Brno) EnemyFactory +getskeleton() : Skeleton * +getmutant() : Mutant * <<instantiate>> EasyEnemyFactory +getskeleton() : Skeleton * +getmutant() : Mutant * HardEnemyFactory +getskeleton() : Skeleton * +getmutant() : Mutant * <<instantiate>> Mutant +~Mutant() +Mutant() +getattack() : int <<instantiate>> <<instantiate>> Skeleton +Skeleton() +~Skeleton() +getattack() : int StrongMutant #m_sila : int #m_jedovatost : int +StrongMutant(sila : int, jedovatost : int) +getattack() : int WeakMutant #m_sila : int +WeakMutant(sila : int) +getattack() : int SkeletonKing -m_siladechu : int +SkeletonKing(silaDechu : int) +getattack() : int SkeletonSoldier -m_silakosti : int +SkeletonSoldier(silaKosti : int) +getattack() : int
Továrny Strana 15 / 28 Abstraktní továrna: přínos Logika vytváření příšer je skryta uvnitř továren. Nikdo nemůže vytvořit chybnou instanci. Dokonce ani neví s jakou instancí pracuje.
Samotáři Strana 16 / 28 Obsah přednášky 1 Co jsou to návrhové vzory 2 Továrny 3 Samotáři 4 Stavitelé 5 Shrnutí
Samotáři Strana 17 / 28 Monostate Problém: Potřebuji mít ve své aplikaci unikátní seznam určitých objektů. Nesmí exitovat více různých seznamů. Potřebuji být navíc schopen z kteréhokoliv místa aplikace k němu přistoupit. Vektory: Potřebuji vytvořit třídu, která bude v sobě slučovat různé matematické operace nad vektory. Řešení: Vytvořím třídu založenou pouze na statických metodách, které umožní práci se statickým seznamem. Tím jednoduše zajistím unikátnost v rámci aplikace. Vektory: vytvořím třídu, která v sobě bude mít statické metody, které vždy provedou příslušnou operaci na předaným vektorem (předanými vektory). Problém: Statické metody nemohou být (čistě) virtuální, proto nepůjde odvozovat potomky tohoto seznamu.
Samotáři Strana 18 / 28 Monostate: příklad Seznam zákazníků Zařid te, aby v aplikaci byl evidován unikátní seznam zákazníků. Třída spravující tento seznam bude poskytovat nástroje pro vyhledání potřebného zákazníka, případně jeho založení. (Měli bychom na konci programu zajistit i uvolnění všech objektů.)
Samotáři Strana 19 / 28 Monostate: příklad Visual Paradigm for UML Standard Edition(Faculty of Business and Economics, Mendel University of Agriculture and Forestry Zakaznik -m_jmeno : string -m_id : int +Zakaznik(jmeno : string, id : int) +getjmeno() : string +getid() : int <<instantiate>> createzakaznik -s_zakaznici SpravceZakazniku -s_pocetzakazniku : int = 0 -s_zakaznici : vector<zakaznik*> = {} +getzakaznikbyjmeno(jmenozakaznika : string) : vector<zakaznik*> +getzakaznikbyid(id : int) : Zakaznik * +createzakaznik(jmenozakaznika : string) : Zakaznik *
Samotáři Strana 20 / 28 Singleton Problém: Potřebuji mít ve své aplikaci objekt, který má jedinou instanci. (Může obsahovat opět určitý seznam (tisková fronta) nebo cokoliv jiného (vstup/výstup dat) atp.) Řešení: Zamezím ručnímu vytváření objektů. Připravíme si statickou metodu, která bud vytvoří novou instanci nebo vrátí existující. Alternativy: Pokud vytvoření objektu stojí mnoho prostředků a budeme jej určitě potřebovat, lze jej vytvořit dopředu (eager init.). Pokud naopak možná potřeba nebude, můžeme jej vytvořit až tehdy, když je potřeba (lazy init.) Problémy: Jak jej smazat? Synchronizace při multivláknovém programování.
Samotáři Strana 21 / 28 Singleton: příklad Seznam chyb Vytvořte logovací třídu, která bude evidovat, kde v programu nastal problém. Při vytvoření objektu se načte seznam předchozích problémů ze souboru. Při ukončení se vše nechá zapsat.
Samotáři Strana 22 / 28 Singleton: příklad Visual Paradigm for UML Standard Edition(Faculty of Business and Economics, Mendel Logger -s_instance : Logger* -m_errors : vector<string> +getlogger() : Logger * +adderror(error : string) : void +storeerrors() : void -Logger() -loaderrors() : void -s_instance
Stavitelé Strana 23 / 28 Obsah přednášky 1 Co jsou to návrhové vzory 2 Továrny 3 Samotáři 4 Stavitelé 5 Shrnutí
Stavitelé Strana 24 / 28 Builder Problém: Potřebujeme vytvořit složitý objekt (dokument, rytíře), který má spoustu součástí. Podle situace, může vytvářený objekt vypadat velmi odlišně. Řešení: Uděláme několik samostatných tříd, které se budou specializovat na tvorbu různých variant vytvářeného objektu. (produktu). Každá třída bude implementovat všechny kroky nezbytné k jeho vytvoření. Řídící třída dostane řečeno, kterého tvůrce použije a zavolá metody pro vytvoření produktu. Není tak nutné volat je ručně. Pozor: Nejedná se o alternativu továrny. Tady se nevyrábí různí potomci produktu, ale stále jen jeden a ten samý produkt. Jen může vypadat různě.
Stavitelé Strana 25 / 28 Builder: příklad Generátor dokumentů Vytvořte kód, který umožní generovat dokumenty různých typů (Latex, XML atp.). Všechny dokumenty budou obsahovat zejména text. Budou se lišit pouze strukturou uloženého textu. Zajistěte, aby se dalo generování v budoucnu rozšířit o další formáty.
Stavitelé Strana 26 / 28 Builder: příklad Visual Paradigm for UML Standard Edition(Faculty of Business and Economics, Mendel University of Agriculture and Forestry in Brno) XmlDocumentBuilder +XmlDocumentBuilder() +buildheader() : void +buildfooter() : void +buildpage(content : string) : void +getsitemap() : string LatexDocumentBuilder -m_encoding : string +LatexDocumentBuilder(encoding : string) +buildheader() : void +buildfooter() : void +buildpage(content : string) : void -buildencoding() : void DocumentBuilder #m_document : Document* +DocumentBuilder() +createnewdocument() : void +buildheader() : void +buildfooter() : void +buildpage(content : string) : void +getdocument() : Document * -m_builder DocumentDirector -m_builder : DocumentBuilder* +DocumentDirector(builder : DocumentBuilder *) +setdocumentbuilder(builder : DocumentBuilder *) : void +constructdocument(text : string) : Document * <<instantiate>> createnewdocument #m_document Document -m_content : string +Document() +addcontent(newcontent : string) : void +getcontent() : string
Shrnutí Strana 27 / 28 Obsah přednášky 1 Co jsou to návrhové vzory 2 Továrny 3 Samotáři 4 Stavitelé 5 Shrnutí
Shrnutí Strana 28 / 28 Shrnutí Prošli jsme si několik vzorů týkajících se vytváření tříd (až na Monostate). Tovární třída (factory method), továrna (factory), abstraktní továrna (abstract factory) jak vytvářet různé typy objektů, jak toto vytváření zapouzdřit na jediné místo v aplikaci. Jedináček (singleton), jednostavový objekt (monostate) potřebujeme zajistit, aby dané od dané třídy existovala pouze jedna instance. Tvůrce (builder) komplexní objekt může mít mnoho různých podob (ale stále je to ten samý objekt), vyváříme ho různými způsoby.