V předminulém týdnu jsem se zúčastnil přednášky Petra Puše (C# MVP) na téma Design Patterns a .NET. Přednáška se konala v malém sále v BB Centru Microsoftu na Praze 4. Přednáška začala s menším zpožděním po 18h a trvala zhruba hodinu a půl. Sál byl díky menší administrativní chybě přeplněný a musela se tak zajistit dodatečná sezení, i na stolech.

Přednáška zahrnovala kromě obecného seznámení a rozdělení návrhových vzorů i konkrétní příklady čtyř jednoduchých vzorů (Singleton, Observer, Proxy a Strategy), které patří mezi jedny z nejpoužívanějších. V začátku přednášky se Petr zabýval obecným významem návrhových vzorů.
Já se vše pokusím v následujících odstavcích shrnout, doplnit a rozšířit.
O design patterns
Design patterns, neboli návrhové vzory, představují osvědčená řešení často opakovaných netriviálních problémů. Jak se Petr zmínil: "Není potřeba znovu vymýšlet kolo." S návrhovými vzory se můžeme setkat v mnohých OOP jazycích, neboť jsou navrženy technologicky nezávisle.
Návrhové vzory nám nejen umožňují řešit netriviální problémy, ale také umožňují snazší komunikaci mezi vývojaři. Pokud chceme jinému vývojaři vysvětlit, jak určitá část kódu funguje a jakou má strukturu, pak to můžeme vyjádřit jedinečným názvem použitého vzoru a ušetřený čas věnovat detailům. Použitím návrhových vzorů tak dosáhneme výsledků mnohem rychleji a kvalitněji.
Řešení může kombinovat několik návrhových vzorů najednou, ale pozor, nic se nemá přehánět! Není bezpodmínečně nutné použít např. 5 návrhových vzorů, když je vhodné použít jen 2.
Návrhové vzory nám též pomáhají najít méně viditelné abstrakce a pomáhají tak při dekompozici (rozklad problému na dílčí podproblémy, které se pak řeší samostatně), na níž během OO (objektově orientovaného) návrhu musíme myslet. Toto jsou některé základní prvky dekompozice:
- Tvorba objektů - způsob vytváření instancí objektů
- Zapouzdření - skrývání složitostí
- Granularita - úroveň složitosti třídy nebo metody a jaké problémy řeší
- Závislost - závislost mezi třídami nebo metodami
- Výkon
- Odpovědnost objektu (koheze)
- Rozšířitelnost
- Znovupoužitelnost - znalost .NET Frameworku a nevynalézání tak již existujících řešení
- a další...
Historie
Návrhové vzory jsou mezi programátory a architekty známy již dlouhá léta a do jejich začátků se musíme vrátit do minulého století.
Základním kamenem se staly designové teorie tradičního architekta Christophera Alexandra[wiki], který ve spolupráci se Sarah Ishikawa a Murray Silverstein[wiki] dal na konci 70. let vzniknout "patterns language"[wiki] (jazyku vzorů). Tento jazyk metodicky popisuje správné použití návrhu na odborné úrovni a byl popsán v knize A Pattern Language: Towns, Buildings, Construction[wiki][seznam vzorů] (ISBN 0195019199) v roce 1977.

V roce 1987 měli Kent Beck[wiki] a Ward Cunningham[wiki][channel9] (tvůrce WikiWikiWeb, první implementace wiki) ze společnosti Tektronix problém s dokončením určitého návrhu ve SmallTalku[wiki], a proto se rozhodli, že vyzkouší něco z oblasti tradičních architektonických vzorů, které si nastudovali. Dokončení návrhu nakonec přenechali zástupcům uživatelů - lektorovi a servisnímu technikovi.

Ward Cunningham mezitím přišel s "jazykem pěti vzorů" (Five pattern language), který měl pomoci nováčkům využít síly SmallTalku a vyvarovat se chyb. Jazyk obsahoval následující vzory:
- WindowPerTask
- FewPanes
- StandardPanes
- NounsAndVerbs
- ShortMenus
Ward Cunningham a Kent Beck byli natolik unešeni elegancí rozhraní, které uživatelé navrhli, že se o výsledky experimentu podělili na OOPSLA 87 (výroční konference Object-Oriented Programming, Systems, Languages & Applications) v Orlandu. V následujících letech se pokračovalo v experimentech a postupnému rozšíření návrhových vzorů v programování.
Nějvětší popularity se návrhovým vzorům v programování dostalo 21.října 1994 (1995 podle copyrightu), kdy vyšla kniha Design Patterns: Elements of Reusable Object-Oriented Software[wiki] (ISBN 0201633612). Autory této knihy, které se v dubnu 2007 dostalo 36. výtisku, jsou Erich Gamma, Richard Helm, Ralph Johnson a John Vlissides. Tato čtveřice je často označována jako Gang of Four, neboli GoF[wiki].

Druhy vzorů
- Návrhové vzory (Design patterns) - vzory, které aplikujeme během fáze návrhu řešení
- Architektonické vzory (Architectural patterns) - aplikační vzory, které nabízejí osvědčená řešení architektonických problémů v softwarovém inženýrství
- Integrační vzory (Integration patterns) - vzory řešící integraci (propojení) systémů
- Vzory nasazení (Deployment patterns) - Vzory pro způsoby nasazení aplikací
- a další...
Rozdělení vzorů
- Tvořivé vzory (Creational patterns) - zabývají se procesem objektové tvorby
- Abstract factory (Abstraktní továrna)
- Factory method (Tovární metoda)
- Builder (Stavitel)
- Lazy initialization
- Object pool (Objektový fond)
- Prototype (Prototyp)
- Singleton (Jedináček)
- Multiton
- Resource acquisition is initialization
- Strukturální vzory (Structural Patterns) - zabývají se skladbou tříd či objektů
- Adapter (Adaptér)
- Bridge (Most)
- Composite (Strom)
- Decorator (Dekorátor)
- Facade (Fasáda)
- Flyweight (Muší váha)
- Proxy (Zástupce)
- Vzory chování (Behavioral patterns) - řeší vzájemnou interakci tříd či objektů a jejich závislosti
- Chain of responsibility (Řetěz odpovědnosti)
- Command (Příkaz)
- Interpreter (Interpret)
- Iterator (Iterátor)
- Mediator (Prostředník)
- Memento (Pamětník)
- Null Object (Null objekt)
- Observer (Pozorovatel)
- State (Stav)
- Strategy (Strategie)
- Specification
- Template method (Šablonová metoda)
- Visitor (Návštěvník)
- Vzory pro souběžné zpracování (Concurrency patterns) - též někdy zmiňovaný typ vzorů, který se zabývá vícevláknovým programováním
- Active Object
- Balking pattern
- Double checked locking pattern
- Guarded suspension
- Leaders/followers pattern
- Monitor Object
- Read write lock pattern
- Scheduler pattern
- Thread pool pattern
- Thread-Specific Storage
- Reactor pattern
Definice vzoru
Dle GoF (Gang of Four) je každý vzor definován s následujícími náležitostmi:
- Název (Pattern Name) - Popisné a unikátní jméno, které umožní jeho identifikaci.
- Skupina (Classification) - Zařazení vzoru do odpovídající skupiny (druh, typ, a další...).
- Účel (Intent) - Popis, co je cílem vzoru a jaké jsou důvody pro jeho použití.
- Jiné názvy (Also Known As) - Další jména pro tento vzor.
- Motivace (Motivation (Forces)) - Scénář skládající se z problému a kontextu, ve kterém je vzor použit
- Struktura (Structure) - Grafická reprezentace vzoru. Pro tento účel se mohou použít Class diagramy nebo interakční modely.
- Použití (Applicability) - Situace, ve kterých je tento vzor použitelný.
- Účastníci (Participants) - Seznam tříd a objektů použitých ve vzoru a jejich role v návrhu.
- Spolupráce účastníků (Collaboration) - Popis, jak třídy a objekty daného vzoru spolupracují mezi sebou.
- Důsledky použití (Consequences) - Popis výsledků, vedlejších efektů a kompromisů způsobených použitím vzoru.
- Známá použití (Known Uses) - Příklady reálného použití vzoru.
- Implementace (Implementation) - Popis implementace vzoru
- Příbuzné vzory (Related Patterns) - Ostatní vzory, které mají nějakou spojitost s tímto vzorem.
- Ukázkový kód (Sample Code) - Ukázkový příklad, jak může být vzor použit v programovacím jazyce.
Závěr
PowerPoint 2007 prezentaci z lednové přednášky Petra Puše (chybí Strategy pattern) si můžete stáhnout zde: Petr-Pus-Design-Patterns-a-.NET.pptx (2.27 mb)
Z Altairisu je možné si stáhnout mix prezentace a audio nahrávky (140 mb).