Návrhové vzory
Základní typy návrhových vzorů, součásti vzoru, způsob použití.
Návrhový vzor (anglicky design pattern) v softwarovém inženýrství představuje obecné řešení problému, které se využívá při návrhu počítačových programů. Návrhový vzor není knihovnou nebo částí zdrojového kódu, která by se dala přímo vložit do našeho programu. Jedná se o popis řešení problému nebo šablonu, která může být použita v různých situacích. Objektově orientované návrhové vzory typicky ukazují vztahy a interakce mezi třídami a objekty, aniž by určovaly implementaci konkrétní třídy. Algoritmy nejsou považovány za návrhové vzory, protože řeší konkrétní problémy a nikoliv problémy návrhu.
Návrhové vzory nepocházejí ze softwarového inženýrství – jsou zcela běžné v každodenním životě. K asi nejznámějším a nejstarším příkladům patří architektura. Gotickou katedrálu poznáte už zdaleka právě proto, že tehdejší architekti a jejich stavební hutě používali stejných návrhových vzorů.
Základní typy návrhových vzorů
Creational Patterns (vytvářející)
Creational Patterns řeší problémy související s vytvářením objektů v systému. 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 těchto objektů. Většinou se jedná o dynamická rozhodnutí učiněná za běhu programu.
Structural Patterns (strukturální)
Structural Patterns představují skupinu návrhových vzorů zaměřujících se 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žností strukturalizace kódu.
Behavioral Patterns (chování)
Behavioral Patterns se zajímají 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.
součásti vzoru
Každý popisovaný návrhový vzor musí být formulován ve formě pravidel, které stanovují vztah mezi kontextem, silami působících v tomto kontextu a konfigurací, která dovoluje těmto silám vyřešit vlastní působení v rámci kontextu.
· Název - každý návrhový vzor by měl mít název, který co možná nejvíce vystihuje jeho podstatu. Jednou z příčin využití návrhových vzorů je usnadnění komunikace mezi lidmi. Proto není možné, aby při použití názvu návrhového vzoru muselo dojít k dlouhému vysvětlení, co daný pojem znamená. Někteří autoři k názvu připojují ještě jeho klasifikaci.
· Problém - každý návrhový vzor řeší nějaký problém. Podstatou jeho vzniku je nějaká konkrétní situace, která neodpovídá požadovanému stavu.
· Podmínky - popis všech okolností a sil, které mohou ovlivňovat použití daného vzoru. Jsou zahrnuty veškeré jevy, které se vyskytují v daném kontextu a které musí být brány v úvahu. Některé síly mohou být využity při řešení, jiné naopak jsou v konfliktu s daným postupem. Dobrý návrhový vzor obsahuje popis všech okolností, za kterých je možné ho použít a které omezují jeho životaschopnost. Obsahuje i popis kontextu, do kterého bude návrhový vzor aplikován. Určuje budoucí možné použití návrhového vzoru nebo nastavení systému před použitím vzoru.
· Řešení - soubor pravidel a vztahů, které popisují jak dosáhnout požadovaného výsledku. Představuje soubor instrukcí, jak postupovat krok po kroku směrem k cíli. Návrhový vzor bývá vysvětlován formou diagramů, obrázků, schémat a popisů, které názorně objasňují základní principy vzoru. Nejedná se většinou o vysvětlení statické struktury návrhového vzoru, ale o zachycení dynamiky daného systému. Právě chování systému při použití návrhového vzoru bývá jeho podstatou. Řešení může obsahovat i popis jednotlivých úskalí a omezení, s kterými se musí počítat při jeho implementaci.
· Příklady - každý popis návrhového vzoru by měl obsahovat i ukázky jeho praktického použití, které pomůžou uživateli osvojit si novou myšlenku. Příklad by měl obsahovat definici konkrétního problému, vstupující podmínky, popis jak je návrhový vzor implementován a výsledek. Příkladem může být například programový kód (pro vzory v oblasti programování), který by měl být co možná nejvíce názorný.
· Výsledek - stav nebo konfigurace systému po aplikaci vzoru, zahrnující vzájemné souvislosti, které vycházejí z implementace vzoru. Měl by obsahovat shrnutí problému, které byly vyřešeny. Aplikací vzoru se mohou vyskytnout určité vedlejší efekty, které nemusí odpovídat požadovanému stavu. Tyto efekty mohou být řešeny následnými návrhovými vzory, které by měly být zmíněny. Jeden návrhový vzor mnohdy nepředstavuje ucelené řešení složitějšího procesu, ale slouží jako jedna z kostek, které jsou použity při hledání vhodného postupu. Proto výsledek použití konkrétního vzoru může tvořit vstupní bod pro aplikaci dalšího vzoru.
· Odůvodnění a souvislosti - představuje vysvětlení, proč byl návrhový vzor použit a jak jeho implementace vyřešila danou situaci. Je vysvětlen způsob práce s návrhovým vzorem v praxi. Tato část popisu návrhového vzoru může ukazovat i na zřejmé výsledky, ale především by se měla soustředit na objasnění principu fungování vzoru do větší hloubky.
· Související vzory - jak už bylo popsáno výše nepředstavuje použití jednoho vzoru většinou ucelené řešení. Mnohdy jsou vstupní podmínky pro použití popisovaného vzoru výsledkem aplikace předchozího a na druhé straně výstupní kontext představuje vstupní bod pro jiný návrhový vzor. Tento řetězec potom dává konečné řešení, kterým je možné dosáhnout požadovaného cíle. Popisovaný způsob řešení daného problému, ale nemusí být jediný a v praxi ani většinou nebývá. Dobrý popis, by měl proto obsahovat i jiné způsoby, kterými je možné se dobrat vytýčeného stavu. Prospěšné je i zmínit okolnosti, na jejichž základě je možné provést výběr mezi navrhovanými postupy. Poslední možností, jak vzor může souviset s ostatními, je nutnost současné aplikace s jiným vzorem. Jedná se o situaci, kdy samostatné použití popisovaného vzoru je buď úplně nebo skoro neefektivní. Pro jeho správnou aplikaci musí být použit jeden nebo i více podpůrných vzorů, které zajišťují jeho plné využití.
· Reference - popisují situace, kdy byl pattern již použit na existujících systémech. Zvyšuje důvěryhodnost schopnosti navrhovaného řešení. Použití návrhového vzoru může sloužit i jako ilustrativní příklad (viz Příklady).
Způsob použití
Návrhové vzory jsou přínosem z mnoha důvodů:
· řeší problémy reálného světa
· zachycují zkušenosti expertů v dané oblasti
· využívají formální struktury pro vyjádření myšlenkový postupů
· vedou začátečníky v oblasti
· vytvářejí slovní zásobu pro diskuse o problémech
· ukazují více než pouze řešení (podmínky řešení, alternativy, cíle, výsledek)
· neomezují možnosti designu, naopak je rozšiřují
· nepřekládají univerzální řešení, ale konkrétní, odpovídající určitým podmínkám
· neposkytují řešení použitelné pouze jednou
Příklad Návrhového vzoru
Abstract Factory Method Pattern - SKUPINA: Creational Patterns - vytvářející
· Problém - Abstract Factory Pattern řeší problém, jak vytvořit na základě rozhodnutí v běhu programu instanci třídy, která dále vytváří instanci souvisejících nebo závislých tříd.
· Podmínky - Abstract Factory představuje o něco vyšší stupeň abstrakce než předchozí Factory Method Patttern. Problém je, že v určitých případech máme více tříd, které vytvářejí instance konkrétních produktů. Každá takové třída vytváří různé typy produktů, jež spolu ovšem nějakým způsobem souvisí. Například odpovídají stejnému uživatelskému rozhraní. Návrhový vzor řeší jak umožnit vybrat za běhu programu jednu z těchto „vytvářejících“ tříd, aniž bychom museli dělat úpravy v celém systému.
Je nutné vytvořit abstraktní třídu pro konkrétní produkty, obdobně jako v předešlém návrhovém vzoru. Místo abstraktní třídy lze využít i rozhraní. Navíc je nutné určit další rozhraní, které bude implementováno konkrétními třídami vytvářející jednotlivé produkty.
· Řešení

Klient vytváří konkrétní instanci třídy typu Factory, která je poděděna z Abstract Factory, nebo implementuje odpovídající rozhraní. Tato konkrétní instance potom vytváří různé objekty (např. Product A 1, Product B 1 pro Concrete Factory 1), které jsou předávány objektu Client.
· Příklad - Rozvineme příklad, který jsem nadefinovali v předchozím návrhovém vzoru. Předpokládejme, že ovoce a zeleninu získává maloobchod ze dvou různých zdrojů. Prvním je domácí pěstitel dodávající ovoce a zeleninu, kterou je schopen vypěstovat. Druhým je dovozce, který se zajišťuje cizí plodiny. Maloobchod získává od obou zdrojů ovoce a zeleninu, ale od každého pouze jeho sortiment (tuzemské nebo z dovozu). Na tomto příkladě je vidět, že produkty vytvářené jednou třídou, musí spolu nějakým způsobem souviset. Když je splněna tato podmínka, získává použití návrhového vzoru smysl.

· Výsledek - Základní výhodou tohoto návrhového vzoru je stejné rozhraní pro různé objekty Concrete Factory. Proto může být kód třídy klienta psán obecně a nezávisle na použití konkrétní instance. Je také velmi jednoduché do aplikace dosadit nový Concrete Factory. Stačí, aby implementoval příslušné rozhraní.
· Odůvodnění a souvislosti - Abstract Factory je využíván, jestliže chceme odstínit klienty od vytváření objektů. Systém může být konfigurovatelný vytvořením několika sad souvisejících objektů. Například každá sada, tvořící uživatelské rozhraní, může komunikovat s uživatelem v jiném jazyce. Klient využívající tento vzor se zajímá pouze o rozhraní a ne o implementaci. Vzor nám umožňuje získat kontrolu nad vytvářením objektů a jednoduchým způsobem lze zaměňovat jednotlivé sady.
Obtížné je zajištění nové třídy typu Concrete Product. Při realizaci takové změny systému je nutné provést opravu rozhraní Abstract Factory a také opravit implementaci všech tříd, které ho využívají.
· Související vzory
· Reference