Vzor adaptéra: popis, funkcie a vlastnosti, pracovné tipy

Adaptér je konštrukčný návrhový vzor používaný na usporiadanie a implementáciu metód objektu, ktoré nie je možné modifikovať pomocou špeciálne navrhnutého rozhrania. V opačnom prípade môžeme povedať, že ide o štruktúrny vzor, ktorý umožňuje vzájomnú interakciu objektov s nekompatibilnými rozhraniami.

Description

Vzor adaptéra sa prispôsobuje medzi triedami a objektmi. Ako každý adaptér na svete okolo nás, šablóna je rozhranie alebo most medzi dvoma objektmi. V reálnom svete máme adaptéry pre napájacie zdroje, pre pevné disky, pre slúchadlá, pre pamäťové karty fotoaparátu atď. Zvážte napríklad niekoľko adaptérov pre pamäťové karty. Ak nie je možné pripojiť pamäťovú kartu fotoaparátu priamo k prenosnému počítaču, môžete použiť adaptér: pamäťová karta fotoaparátu je pripojená k adaptéru a adaptér je pripojený ku konektoru prenosného počítača. Tým sa vyrieši problém nekompatibility rozhrania.

Adaptér: návrhový vzor a rozhranie

V prípade vývoj softvéru , všetko je asi rovnako. Môžete si predstaviť situáciu, keď na nejaký typ objektu čaká nejaká trieda A existuje objekt ponúkajúci rovnakú funkčnosť, ale s iným rozhraním. Samozrejme, bude výhodné použiť obe z nich, aby sa jedno z rozhraní neimplementovalo opakovane a aby sa nezmenili existujúce triedy. V takejto situácii by bolo rozumné použiť adaptér na návrh softvéru.

Realizácia

Na nasledujúcom obrázku je znázornený diagram triedy UML vzoru adaptéra.

Adaptér: UML diagram

Triedy a objekty zapojené do návrhového vzoru:

  1. (Target) - definuje rozhranie špecifické pre doménu, ktoré klient používa.
  2. (Adaptér) - prispôsobuje rozhranie (Adaptee) cieľovému rozhraniu.
  3. (Adaptee) - definuje existujúce rozhranie, ktoré je potrebné prispôsobiť.
  4. (Klient) - interaguje s objektmi zodpovedajúcimi rozhraniu (cieľ).

Aplikácia

Vzor adaptéra sa používa v nasledujúcich prípadoch:

  • Keď existuje trieda (cieľ), ktorá volá metódy definované v rozhraní. Okrem toho existuje ďalšia trieda (adaptér), ktorá neimplementuje rozhranie, ale implementuje operácie a metódy, ktoré by sa mali volať z prvej triedy cez rozhranie. Programátor nemá žiadny spôsob, ako zmeniť niektorý z existujúcich kódov. Adaptér implementuje svoje rozhranie a stane sa mostom medzi týmito dvoma triedami.
Vzor adaptéra: vytvorenie projektu
  • Pri písaní triedy (cieľa) na všeobecné použitie je dôležité spoliehať sa na niektoré bežné rozhrania a vývojár má niektoré implementované triedy, ktoré rozhranie neimplementujú. Aj táto trieda (cieľ) by sa mala nazývať.

Dobrým príkladom použitia adaptéra sú obaly používané na prijímanie knižníc a štruktúr tretích strán: väčšina aplikácií využívajúcich knižnice tretích strán používa adaptér ako medzivrstvu medzi aplikáciou a knižnicou tretích strán na oddelenie aplikácie od knižnice. Ak potrebujete použiť inú knižnicu, nová knižnica vyžaduje iba adaptér bez toho, aby ste museli meniť kód aplikácie.

Adaptéry objektov založené na delegovaní

Objekt adaptéra je klasickým príkladom šablóny adaptéra. Používa kompozíciu a (Adaptee) deleguje hovory na seba, čo nie je k dispozícii adaptérom tried, ktoré rozširujú (Adaptee). Toto správanie nám dáva niekoľko výhod oproti adaptérom triedy, ale adaptéry triedy je možné implementovať v jazykoch, ktoré umožňujú viacnásobné dedičstvo. Hlavnou výhodou je, že (adaptér) prispôsobuje nielen (Adaptee), ale aj všetky jeho podtriedy. Všetky tieto podtriedy existujú s jedným "malý" obmedzenie: všetci nemôžu pridávať nové metódy, pretože použitý mechanizmus je delegovanie. Takže pre každú novú metódu musí byť adaptér upravený alebo rozšírený, aby poskytoval nové metódy. Hlavnou nevýhodou je, že vyžaduje napísanie nového kódu na delegovanie všetkých potrebných požiadaviek na adaptér.

Adaptéry triedy založené na (viacnásobnom) dedičstve

Adaptéry triedy môžu byť implementované v jazykoch, ktoré podporujú viacnásobné dedičstvo. Programovacie jazyky Java, C# alebo PHP nepodporujú viacnásobné dedičstvo, ale majú rozhrania. Takéto vzory teda nemožno v týchto jazykoch ľahko implementovať. Dobrým príkladom programovacieho jazyka, kde môžete ľahko implementovať dizajn, je jazyk C.

Vzor adaptéra používa dedičnosť namiesto zloženia. To znamená, že namiesto delegovania hovorov (Adaptee) ho zdedí. Na záver, adaptér triedy by mal byť rozdelený do podtried a (cieľ) a sám (adaptér).

Adaptér založený na viacnásobnom dedičstve

Tento prístup má svoje výhody a nevýhody:

  • Vzor prispôsobuje určitú triedu (Adaptee). Trieda rozširuje túto adaptáciu. Ak túto podtriedu nie je možné prispôsobiť existujúcim adaptérom.
  • Šablóna nevyžaduje všetok kód, potrebné pre delegácia, ktorá musí byť napísaná pre triedu (adaptér).
  • Ak je objekt (cieľ) reprezentovaný skôr rozhraním ako triedou, môžeme hovoriť o "trieda" adaptéry, pretože môžeme implementovať toľko rozhraní, koľko chceme.

Obojsmerné adaptéry

Obojsmerné adaptéry sú adaptéry, ktoré implementujú obe rozhrania: (Target) aj (Adaptee). Upravený objekt je možné použiť ako (Target) v nových systémoch pracujúcich s triedami( Target), alebo ako (Adaptee) v ostatné systémy, práca s triedami (Adaptee). Ak pôjdeme týmto smerom ďalej, potom môžeme mať adaptéry, ktoré implementujú n-tý počet rozhraní, ktoré sa prispôsobia n-systémom. Obojsmerné adaptéry a n-way adaptéry sa ťažko implementujú v systémoch, ktoré nepodporujú viacnásobné dedičstvo. Ak adaptér musí rozšíriť triedu (cieľ), nemôže rozšíriť ďalšiu triedu, napríklad (Adaptee), preto (Adaptee) musí byť rozhranie a všetky hovory je možné delegovať z adaptéra na objekt (Adaptee).

Použitie šablóny adaptéra vo vývoji VR

Okrem toho, ak sú (Target) a (Adapter) podobné, potom by adaptér mal jednoducho delegovať požiadavky z triedy (Target) na triedu (Adapter), a ak (Target) a (Adaptee) nie sú navzájom podobné, potom môže byť potrebné, aby adaptér transformoval dátové štruktúry medzi nimi a implementoval operácie potrebné pre (Target), ale nie implementované v triede (Adaptee).

Príklad implementácie

Predpokladajme, že máme triedu (Vták) s metódami fly ()a makeSound (). A tiež trieda (ToyDuck) s metódou Squeak (). Povedzme, že máme málo objektov (ToyDuck) a chceme namiesto nich používať objekty (Bird. Vtáky majú podobnú funkčnosť, ale implementujú iné rozhranie, takže ich nemôžeme použiť priamo. Preto budeme používať šablónu adaptéra. Tu bude náš (klient) (ToyDuck) a (Adaptee) bude (Vták). Nižšie je uvedený príklad implementácie návrhu vzoru adaptéra v jazyku Java, ktorý je jedným z najbežnejších programovacie jazyky.

rozhranieVták{verejnýneplatnýlietať();verejnýneplatnýmakeSound();}triedaSparrowimplementovaťVták{verejnýneplatnýlietať(){Systém.von.println("Lietania");}verejnýneplatnýmakeSound(){Systém.von.println("Chirp Chirp");}}rozhranieToyDuck{verejnýneplatnýprihlásiť sa();}triedaPlasticToyDuckimplementovaťToyDuck{verejnýneplatnýprihlásiť sa(){Systém.von.println("Prihlásiť sa");}}triedaBirdAdapterimplementovaťToyDuck{Vták Vták;verejnýBirdAdapter(Vták Vták){tento.vták = vták;}verejnýneplatnýprihlásiť sa(){vták.makeSound();}}triedaHlavný{verejnýstatickýneplatnýhlavný(String args[]){Vrabec vrabec =novýSparrow();ToyDuck toyDuck =novýPlasticToyDuck();ToyDuck birdAdapter =novýBirdAdapter(sparrow);Systém.von.println("Sparrow...");sparrow.lietať();sparrow.makeSound();Systém.von.println("ToyDuck...");toyDuck.prihlásiť sa();Systém.von.println("BirdAdapter...");birdAdapter.prihlásiť sa();}}

Predpokladajme, že máme vtáka, ktorý dokáže vydávať zvuk(), a plastovú hračku, ktorá môže škrípať-škrípať (). Teraz Predpokladajme, že náš (klient) zmení požiadavku a chce (ToyDuck) vykonať zvuk (), ale ako?

Príklad dizajnu založeného na vzore adaptéra

Riešením je, že jednoducho zmeníme implementačnú triedu na novú triedu adaptérov a povieme klientovi, aby odovzdal inštanciu vtáka do tejto triedy. To je všetko. Teraz zmenou iba jedného riadku naučíme (ToyDuck) tweetovať ako vrabec.

Články na tému