Programovanie

Úvod do návrhových vzorov, časť 1: História a klasifikácia návrhových vzorov

Bolo vyvinutých veľa stratégií na zjednodušenie a zníženie nákladov na navrhovanie softvéru, najmä v oblasti údržby. Naučiť sa, ako identifikovať a pracovať s opakovane použiteľnými softvérovými komponentmi (občas sa označuje ako softvérové ​​integrované obvody) je jedna stratégia. Použitie dizajnových vzorov je ďalšie.

Tento článok uvádza na trh trojdielnu sériu dizajnových vzorov. V tejto časti predstavím koncepčný rámec návrhových vzorov a prejdem ukážkou vyhodnotenia návrhového vzoru pre konkrétny prípad použitia. Budem tiež diskutovať o histórii dizajnových vzorov a anti-vzorov. Na záver klasifikujem a sumarizujem najpoužívanejšie vzory návrhu softvéru, ktoré boli objavené a zdokumentované za posledných pár desaťročí.

Čo je dizajnový vzor?

Navrhovanie opakovane použiteľného objektovo orientovaného softvéru, ktorý modeluje existujúci systém, je skutočne náročné. Softvérový vývojár musí rozčleniť entity systému do tried, ktorých verejné rozhrania nie sú príliš zložité, nadviazať vzťahy medzi triedami, vystaviť hierarchie dedičstva a ďalšie. Pretože väčšina softvéru sa naďalej používa dlho po jeho napísaní, vývojári softvéru musia tiež zodpovedať súčasným požiadavkám na aplikácie a zároveň udržiavať svoj kód a infraštruktúru dostatočne flexibilné, aby vyhovovali budúcim potrebám.

Skúsení objektovo orientovaní vývojári zistili, že vzory návrhu softvéru uľahčujú kódovanie stabilných a robustných softvérových systémov. Efektívne použitie týchto návrhových vzorov namiesto neustáleho vývoja nových riešení od základu je efektívne a znižuje sa tak riziko chyby. Každý návrhový vzor identifikuje opakujúci sa problém s návrhom v konkrétnom kontexte aplikácie, potom ponúka zovšeobecnené, opakovane použiteľné riešenie, ktoré je použiteľné pre rôzne aplikačné scenáre.

„A dizajnový vzor opisuje triedy a interagujúce objekty, ktoré sa používajú na vyriešenie všeobecného problému s dizajnom v konkrétnom kontexte. “

Niektorí vývojári definujú a dizajnový vzor ako entita kódovaná triedou (napríklad prepojený zoznam alebo bitový vektor), zatiaľ čo iní tvrdia, že návrhový vzor je v celej aplikácii alebo podsystéme. Môj názor je, že a dizajnový vzor popisuje triedy a interagujúce objekty, ktoré sa používajú na riešenie všeobecného problému s dizajnom v konkrétnom kontexte. Formálnejšie je vzor návrhu špecifikovaný ako popis, ktorý pozostáva zo štyroch základných prvkov:

  1. A názov ktorý popisuje návrhový vzor a dáva nám slovník na diskusiu
  2. A problém ktorá identifikuje problém návrhu, ktorý je potrebné vyriešiť, spolu s kontextom, v ktorom sa problém vyskytuje
  3. A Riešenie k problému, ktorý (v kontexte vzoru softvérového dizajnu) by mal identifikovať triedy a objekty, ktoré prispievajú k návrhu, spolu s ich vzťahmi a ďalšími faktormi
  4. Vysvetlenie následky použitia návrhového vzoru

Aby ste určili vhodný návrhový vzor, ​​ktorý sa má použiť, musíte najskôr jasne identifikovať problém, ktorý sa snažíte vyriešiť; to je miesto, kde problém prvok popisu vzoru je užitočný. Výber jedného návrhového vzoru pred iným tiež zvyčajne zahŕňa kompromisy, ktoré môžu mať vplyv na flexibilitu aplikácie alebo systému a budúcu údržbu. Preto je dôležité pochopiť následky použitia daného návrhového vzoru skôr, ako ho začnete implementovať.

Hodnotenie návrhového vzoru

Zvážte úlohu návrhu zložitého používateľského rozhrania pomocou tlačidiel, textových polí a iných nekontejnerových komponentov. Kompozitný návrhový vzor považuje kontajnery za komponenty, čo nám umožňuje vkladať kontajnery a ich komponenty (kontajnery a nekontejnery) do iných kontajnerov, a to rekurzívne. Ak by sme sa rozhodli nepoužívať kompozitný vzor, ​​museli by sme vytvoriť veľa špecializovaných nekontejnerových komponentov (jeden komponent kombinujúci napríklad textové pole hesla a prihlasovacie tlačidlo), čo je ťažšie dosiahnuť.

Keď to premyslíme, pochopíme problém, ktorý sa snažíme vyriešiť, a riešenie ponúkané zloženým vzorom. Aké sú však dôsledky použitia tohto modelu?

Použitie Composite znamená, že vaše hierarchie tried budú miešať komponenty kontajnera a bez kontajnera. Jednoduchší klienti budú s komponentmi kontajnera a bez kontajnera zaobchádzať jednotne. A bude jednoduchšie zaviesť do používateľského rozhrania nové druhy komponentov. Kompozitný môže tiež viesť k príliš zovšeobecnený vzory, čo sťažuje obmedzenie druhov komponentov, ktoré je možné pridať do kontajnera. Pretože sa nebudete môcť spoľahnúť na to, že kompilátor vynúti obmedzenia typu, budete musieť použiť kontroly typu za behu.

Čo je zlé na kontrole typu za behu?

Zahŕňajú kontroly typu za behu ak vyhlásenia a inštancia operátor, čo vedie k krehkému kódu. Ak zabudnete aktualizovať kontrolu typu runtime s vývojom požiadaviek na aplikáciu, mohli by ste následne zaviesť chyby.

Je tiež možné zvoliť vhodný dizajnový vzor a použiť ho nesprávne. The Dvojitá kontrola blokovania vzor je klasický príklad. Dvojitá kontrola blokovania znižuje réžiu získania zámku najprv testovaním kritéria blokovania bez skutočného získania zámku a následným získaním zámku iba v prípade, že kontrola naznačuje, že je potrebné blokovanie. Aj keď to na papieri vyzeralo dobre, zamykanie s dvojitou kontrolou v JDK 1.4 malo niektoré skryté zložitosti. Keď JDK 5 rozšíril sémantiku súboru prchavý kľúčové slovo, vývojári mohli konečne využívať výhody vzoru dvojitej kontroly zamykania.

Viac informácií o dvakrát skontrolovanom uzamknutí

Pozri „Dvojité skontrolovanie blokovania: Chytré, ale zlomené“ a „Môže byť dvojité skontrolovanie blokovania pevné?“ (Brian Goetz, JavaWorld), kde sa dozviete viac o tom, prečo tento vzor nefungoval v JDK 1.4 a starších. Viac informácií o špecifikovaní DCL v JDK 5 a novších nájdete v „Deklarácii„ Double-Checked Locking is Broken 'Broken “(Oddelenie informatiky univerzity v Marylande, David Bacon a kol.).

Anti-vzory

Ak sa návrhový vzor bežne používa, ale je neúčinný a / alebo kontraproduktívny, je návrhový vzor známy ako anti-vzor. Niekto by mohol namietať, že zamknutie s dvojitou kontrolou, ako sa používa v JDK 1.4 a starších, bolo anti-vzorom. Povedal by som, že to bol v tomto kontexte iba zlý nápad. Aby sa zlý nápad vyvinul do anti-vzoru, musia byť splnené nasledujúce podmienky (pozri Zdroje).

  • Opakovaný vzorec akcie, procesu alebo štruktúry, ktorý sa spočiatku javí ako prospešný, ale v konečnom dôsledku prináša viac zlých dôsledkov ako priaznivých výsledkov.
  • Existuje alternatívne riešenie, ktoré je jasne zdokumentované, preukázané v praxi a opakovateľné.

Zatiaľ čo dvojitá kontrola zamykania v JDK 1.4 spĺňala prvú požiadavku anti-vzoru, nespĺňala druhú: hoci ste mohli použiť synchronizované pri riešení problému lenivej inicializácie vo viacvláknovom prostredí by to bolo na prvom mieste prekonané kvôli použitiu uzamknutia s dvojitou kontrolou.

Zablokované anti-vzory

Rozpoznanie anti-vzorov je nevyhnutným predpokladom na ich zabránenie. Prečítajte si trojdielnu sériu Obi Ezechukwu pre úvod k trom anti-vzorom, ktoré sú známe tým, že spôsobili patovú situáciu:

  • Žiadna arbitráž
  • Agregácia pracovníkov
  • Inkrementálne blokovanie

História návrhových vzorov

Dizajnové vzory sa datujú koncom 70. rokov 20. storočia po publikácii Vzorový jazyk: mestá, budovy, stavby od architekta Christophera Alexandra a niekoľkých ďalších. Táto kniha predstavila dizajnové vzory v architektonickom kontexte a predstavuje 253 vzorov, ktoré spoločne tvoria to, čo autori nazvali a vzorový jazyk.

Irónia dizajnových vzorov

Aj keď návrhové vzory použité pri softvérovom dizajne, ich počiatky až do začiatku Vzorový jazyk, toto architektonické dielo bolo ovplyvnené vtedy vznikajúcim jazykom na opisovanie programovania a dizajnu počítačov.

Koncept vzorového jazyka sa následne objavil u Donalda Normana a Stephena Drapera Návrh systému zameraného na používateľa, ktorá bola publikovaná v roku 1986. Táto kniha navrhla aplikáciu vzorových jazykov na interakčný dizajn, čo je prax navrhovania interaktívnych digitálnych produktov, prostredí, systémov a služieb pre ľudské použitie.

Medzitým Kent Beck a Ward Cunningham začali študovať vzory a ich použiteľnosť pri softvérovom dizajne. V roku 1987 použili sériu návrhových vzorov na pomoc skupine spoločnosti Tektronix Semiconductor Test Systems Group, ktorá mala problémy s dokončením projektového projektu. Beck a Cunningham sa riadili Alexandrovými radami pre dizajn zameraný na používateľa (nechať zástupcov používateľov projektu určiť výsledok návrhu) a zároveň im poskytnúť niektoré vzory návrhu, ktoré uľahčujú prácu.

Erich Gamma si tiež uvedomil dôležitosť opakujúcich sa návrhových vzorov pri svojej dizertačnej práci. Veril, že návrhové vzory by mohli uľahčiť úlohu písania opakovane použiteľného objektovo orientovaného softvéru, a uvažoval o tom, ako ich efektívne dokumentovať a komunikovať. Pred európskou konferenciou o objektovo orientovanom programovaní v roku 1991 začali spoločnosti Gamma a Richard Helm katalogizovať vzory.

Na workshope OOPSLA, ktorý sa konal v roku 1991, sa ku Gama a Helmovi pripojili Ralph Johnson a John Vlissides. Toto Gang štyroch (GoF), ako boli následne známi, ďalej písali populárne Dizajnové vzory: Prvky opakovane použiteľného objektovo orientovaného softvéru, ktorý dokumentuje 23 dizajnových vzorov v troch kategóriách.

Moderná evolúcia dizajnových vzorov

Dizajnové vzory sa od pôvodnej knihy GoF naďalej vyvíjajú, najmä keď vývojári softvéru čelili novým výzvam súvisiacim so zmenou hardvérových a aplikačných požiadaviek.

V roku 1994 bola slávnostne otvorená americká nezisková organizácia známa ako Hillside Group Vzorové jazyky programov, skupina výročných konferencií, ktorých cieľom je rozvíjať a zdokonaľovať umenie vzorov softvérového dizajnu. Tieto prebiehajúce konferencie priniesli veľa príkladov návrhových vzorov špecifických pre doménu. Napríklad návrhové vzory v kontexte súbežnosti.

Christopher Alexander v OOPSLA

Hlavný prejav OOPSLA 96 predniesol architekt Christopher Alexander. Alexander sa zamyslel nad svojou prácou a nad tým, ako objektovo orientovaná komunita programovania zasiahla a minula cieľ pri prijímaní a prispôsobovaní svojich predstáv o vzorových jazykoch softvéru. Alexandrovu adresu si môžete prečítať v úplnom znení: „Počiatky teórie vzorov: budúcnosť teórie a generácia živého sveta“.

V roku 1998 Mark Grand prepustený Vzory v Jave. Táto kniha obsahovala návrhové vzory, ktoré sa v knihe GoF nenašli, vrátane vzorov súbežnosti. Grand tiež použil Unified Modeling Language (UML) na popísanie návrhových vzorov a ich riešení. Príklady knihy boli vyjadrené a popísané v jazyku Java.

Softvérové ​​návrhové vzory podľa klasifikácie

Moderné vzory návrhu softvéru sú zhruba rozdelené do štyroch kategórií na základe ich použitia: tvorivé, štrukturálne, behaviorálne a súbežné. Budem diskutovať o každej kategórii a potom uvediem a popíšem niektoré z prominentných vzorov pre každú z nich.

Iné typy dizajnových vzorov

Ak si myslíte, že existuje viac druhov vzorov, máte pravdu. Neskôr uvedený článok v tejto sérii pojednáva o ďalších typoch návrhových vzorov: interakčné, architektonické, organizačné a komunikačné / prezentačné vzory.

Tvorivé vzory

A tvorivý vzor abstrahuje proces inštancie a oddeľuje spôsob vytvárania, skladania a reprezentácie objektov od kódu, ktorý sa na ne spolieha. Triedne kreačné vzory použiť dedičstvo na zmenu tried, ktoré sú inštancované, a objekty tvorivé vzory delegovať inštanciu na iné objekty.

  • Abstraktná továreň: Tento vzor poskytuje rozhranie na zapuzdrenie skupiny jednotlivých tovární, ktoré majú spoločnú tému, bez uvedenia konkrétnych tried.
  • Staviteľ: Oddeľuje konštrukciu zložitého objektu od jeho znázornenia, čo umožňuje rovnakému procesu výstavby vytvárať rôzne znázornenia. Abstrahovanie krokov konštrukcie objektu umožňuje rôznym implementáciám krokov zostrojiť rôzne znázornenia objektov.
  • Továrenská metóda: Definuje rozhranie na vytvorenie objektu, ale umožňuje podtriedam rozhodnúť, ktorá trieda sa má vytvoriť. Tento vzor umožňuje triede odložiť inštanciu do podtried. Závislosť injekcie je príbuzný vzor. (Pozri zdroje.)
  • Lenivá inicializácia: Tento vzor nám poskytuje spôsob, ako oddialiť vytvorenie objektu, vyhľadanie databázy alebo iný drahý proces, kým nie je potrebný prvý raz výsledok.
  • Multiton: Rozširuje koncepciu singleton o správu mapy inštancií pomenovaných tried ako párov kľúč - hodnota a poskytuje k nim globálny prístupový bod.
  • Bazén objektov: Udržujte sadu inicializovaných objektov pripravenú na použitie, namiesto toho, aby boli alokované a zničené na požiadanie. Zámerom je zabrániť nákladnému získavaniu a rekultivácii zdrojov recykláciou predmetov, ktoré sa už nepoužívajú.
  • Prototyp: Určuje druhy objektov, ktoré sa majú vytvoriť pomocou prototypovej inštancie, a potom vytvorí nové objekty skopírovaním tohto prototypu. Prototypová inštancia je klonovaná na generovanie nových objektov.
  • Získavanie zdrojov je inicializácia: Tento vzor zaisťuje, že zdroje sú automaticky a správne inicializované a regenerované ich viazaním na životnosť vhodných objektov. Zdroje sa získavajú počas inicializácie objektu, keď neexistuje šanca, že sa použijú skôr, ako budú k dispozícii, a uvoľnia sa spolu so zničením tých istých objektov, ku ktorému zaručene dôjde aj v prípade chýb.
  • Singleton: Zaisťuje, že trieda má iba jednu inštanciu, a poskytuje globálny prístupový bod k tejto inštancii.
$config[zx-auto] not found$config[zx-overlay] not found