Návrhové vzory
Neobjevovat Ameriku, nevynalézat kolo 
Programování, podobně jako většina lidských činností, má svá "hesla dne". Kdo se jimi dostatečně často nezaklíná, není "in", nemůže být považován za odborníka. V sedmdesátých letech minulého století to bylo strukturované programování, před deseti lety to bylo objektově orientované programování, dnes to jsou mimo jiné návrhové vzory. 

To ale neznamená, že jde jen o prázdná módní slova: mnohá z těchto hesel mají hluboký obsah a za masivním marketingem a propagandou téměř bolševického ražení se mohou skrývat - i když se to člověku občas nechce věřit - velice užitečné věci. To platí i o návrhových vzorech.  

O co jde 
Co to vlastně ty návrhové vzory, anglicky design patterns, vlastně jsou? 
Odpověď je poměrně jednoduchá: Jde o popisy řešení nejběžnějších problémů, s nimiž se vývojáři při návrhu softwaru setkávají. Je jasné, že pro to, aby se určitý postup stal návrhovým vzorem, nestačí, aby poskytoval správné řešení pro jednu situaci. Řešení musí být použitelné pro celou třídu podobných situací. Musí ovšem také jít o řešení, které se ukazuje jako nejvýhodnější z hlediska přenositelnosti, rozšiřitelnosti, udržovatelnosti a řady dalších požadavků, které se na vyvíjený software obvykle kladou (ale ne vždy se pak dodržují). 
Pokud vám to zní povědomě, nedivte se. Ono ve skutečnosti nejde o nic nového: svá ustálená řešení, tedy své návrhové vzory, má většina oborů tvůrčí lidské činnosti, architekturou počínaje a psaním románů nebo televizních seriálů konče. 
Návrhové vzory pro tvorbu programů jsou založeny na objektově orientovaném přístupu, i když realizace řady z nich v konkrétním programovacím jazyce objektová už být nemusí. Většina návrhových vzorů nemá žádného konkrétního autora, vznikla postupným, v podstatě darwinovským vývojem mezi programátory, často na mnoha místech zároveň. 
Poměrně dlouhou dobu ovšem trvalo, než si lidé uvědomili jejich existenci, a především jejich cenu. I když programátorská profese existuje už od počátku padesátých let minulého století, teprve na počátku devadesátých let se nad návrhovými vzory vážně zamyslela čtveřice špičkových programátorů a softwarových architektů (Erich Gamma, Richard Helm, Ralph Johnson a John Vlissides), posbírala nejběžnější z nich, utřídila je a v roce 1995 o nich vydala knihu s prostým názvem Design Patterns [1]. 
Trvalo ovšem ještě nějakou dobu, než programátoři začali význam návrhových vzorů plně doceňovat. V běžných učebnicích programování se o nich začalo hovořit vlastně až na samém konci devadesátých let; v současné době se znalost základních návrhových vzorů a schopnost jejich rozpoznání stává jedním z požadavků, který softwarové firmy kladou na uchazeče o přijetí na místo programátora. 
Poznamenejme, že kniha [1] vykládá základní návrhové vzory pomocí jazyka C++, občas také pomocí Smalltalku. Od té doby se ve světové literatuře objevila řada dalších knih o návrhových vzorech založených na jiných jazycích (např. na Javě), většinou jde ovšem o převyprávění [1]. Pokud mohu posoudit, nedosahují ani zdaleka kvality původní publikace (i když může jít o důsledek skutečnosti, že mezi programovacími jazyky dávám přednost právě C++).  

Příklad 
Někdy potřebujeme, aby jistá třída - řekněme třída X - měla pouze jedinou instanci. I když to možná na první pohled vypadá podivně, nejde o nic výjimečného. Může jít např. o třídu představující souborový systém v operačním systému nebo o třídu představující řadič tiskových úloh (spooler) v lokální počítačové síti. Ve skutečnosti jde o natolik častou situaci, že pro ni stálo za to vytvořit samostatný návrhový vzor, označovaný jako jedináček neboli singleton. 

Druhy návrhových vzorů 
Autoři knihy [1] rozdělili návrhové vzory do tří základních skupin a toto rozdělení dodržuje i většina dalších autorů, kteří o návrhových vzorech píší. 
První skupina obsahuje tvořivé (kreacionální) návrhové vzory. To jsou vzory, které popisují různé způsoby vytváření instancí objektových typů. Pomáhají zkonstruovat systém, který je nezávislý na podrobnostech způsobu vytváření a skládaní objektů, které ho tvoří. 
Druhou skupinu tvoří strukturální návrhové vzory, které se zabývají způsoby sestavování tříd nebo jednotlivých objektů do složitějších struktur. 
Poslední skupinu tvoří návrhové vzory chování (behaviorální vzory). Ty se, stručně řečeno, zabývají algoritmy a rozdělením úkolů mezi jednotlivé objekty. Kromě samotných objektů nebo tříd popisují také způsoby komunikace mezi nimi, řídicí procesy, které se zde uplatňují, atd.  

Tvořivé vzory 
Už jsme si řekli, že jde o návrhové vzory, které popisují způsoby vytváření objektů, tedy instancí objektových typů. Zapouzdřují: 
* informace o tom, jaké třídy systém používá; 
* informace o tom, jak se instance těchto tříd vytvářejí. 
Výsledkem je, že systém zná pouze rozhraní objektů, s nimiž pracuje, a tím získává nezávislost na skutečném typu použitých objektů. Jednoduchým příkladem tvořivého vzoru je už zmíněný jedináček. Jiným příkladem je abstraktní továrna (abstract factory); s jejími variantami se setkáme např. v automaticky generovaném kódu při programování komponent COM. V objektových knihovnách se často také setkáme s tovární metodou.  

Strukturální vzory 
Tyto vzory popisují, jak víme, varianty návrhu struktury tříd. Přitom využívají buď skládání objektů, nebo dědičnost. Cílem může být: 
* skládání nebo změna funkčnosti (tedy implementace); 
* skládání nebo změna rozhraní objektů nebo tříd. 
Příkladem strukturálního vzoru je adaptér. Tento návrhový vzor umožňuje přizpůsobit rozhraní existující třídy požadavkům jejího použití. Jestliže máme např. k dispozici třídu představující frontu a potřebujeme zásobník, vytvoříme zásobník jako adaptér, který zapouzdří frontu do třídy s potřebným rozhraním. Jiným běžným příkladem strukturálního vzoru je most (bridge), v anglické literatuře také označovaný jako the pimpl idiom. (Pimpl je zkratka slov pointer to implementation, tedy ukazatel na implementaci, a v podstatě vystihuje způsob implementace.) Tento vzor umožňuje od sebe oddělit rozhraní a implementaci třídy tak, že implementaci lze měnit i za běhu programu. 
Poznamenejme, že mnohé strukturální vzory jsou v různé míře příbuzné a za určitých situací je lze zaměnit.  

Vzory chování 
Tyto návrhové vzory se zabývají algoritmy a rozdělením povinností mezi objekty. Nepopisují jen skladbu objektů či tříd, ale také způsoby komunikace mezi nimi. Často charakterizují složité řídicí procesy, které je obtížné sledovat za běhu. Umožňují nám místo procesu řízení sledovat jen způsob propojení mezi objekty. 
Jedním z nejčastěji používaných vzorů chování jsou iterátory - objekty, na které se můžeme dívat jako na zobecnění ukazatelů na prvky polí nebo jejich indexů. Umožňují pracovat stejným způsobem s různými druhy kontejnerů, nejen s poli. 
Jiným často používaným vzorem je pozorovatel (observer), označovaný také jako vzor vydavatel-předplatitel (publisher-subscriber). Tento návrhový vzor řeší situaci, kdy různé komponenty programu musí reagovat na změnu některého objektu. Přitom zpravidla není známo, které komponenty a v jakou dobu to budou.  

Použití návrhových vzorů 
I když používání návrhových vzorů není zatím mezi řadovými programátory příliš rozšířené, tvůrci knihoven a vývojových nástrojů si již delší dobu nemohou dovolit je pomíjet. To znamená, že s návrhovými vzory se již zcela běžně setkáváme v různých objektových knihovnách a ve zdrojovém kódu automaticky generovaném vývojovými nástroji. 
Podívejme se na několik namátkou vybraných příkladů: 
* Standardní způsob zpracování událostí v Javě je založen na návrhovém vzoru pozorovatel. 
* Pro práci se sekvenčními kontejnery se ve standardní šablonové knihovně C++ (STL), ale i v knihovnách Javy nebo C#, používají iterátory. 
* Šablona zásobníku je v STL vytvořena jako adaptér využívající vektor, seznam nebo dvoustrannou frontu. 
* Instance tříd automaticky generovaných vývojovými prostředími pro tvorbu aplikací CORBA nebo COM na základě jazyka IDL jsou zpravidla vytvářeny pomocí abstraktních továren a implementace těchto tříd je založena na vzoru most.  

Co z toho plyne?  
Na návrhové vzory se můžeme dívat jako na analogii matematických, geometrických, fyzikálních a jiných vzorečků, které se učíme na základní škole a které nás pak provázejí po celý život. Chceme-li si spočítat plochu koberce, protože čistírna nepřijímá větší než 5 m2, změříme si jeho strany a pak použijeme vzorec pro výpočet plochy obdélníka. Ten samozřejmě neodvozujeme, ten známe, neboť patří k základnímu vzdělání. Návrhové vzory v programování dnes začínají hrát podobnou roli při tvorbě počítačových aplikací. Podrobnější článek o návrhových vzorech najdete na Chip CD. 
Miroslav Virius	

Literatura: 
[1] Erich Gamma, Richard Helm, Ralph Johnson a John Vlissides: Design Patterns. Addison-Wesley 1995. Český překlad Návrh programů podle vzorů, Grada Publishing 2003. Na tuto knihu mnozí autoři odkazují značkou GoF, což je zkratka anglických slov Gang of Four - parta čtyř.