Adapter (wrapper)
Návrhový vzor Adapter (alebo tiež Wrapper) sa používa pri práci s komponentom, ktorá má nestabilné alebo s našou aplikáciou nekompatibilný rozhrania. Umožňuje komponent obaliť naším rozhraním a tak aplikáciu úplne odtieniť od rozhrania pôvodného.
Motivácia
Väčšina z vás iste pri vývoji používa komponentovú architektúru a využíva teda hotových riešení tretích strán (alebo vlastných komponentov z predošlých projektov). Predstavme si, že chceme (alebo dokonca musíme) používať komponent, ktoré jej autori stále mení rozhranie. My túto komponent používame na 100 miestach v programe a pri každej novej verzii musíme kód na mnohých miestach prepisovať. Podobný problém nastane v prípade, keď máme v aplikácii už pripravené nejaké rozhranie a chceme do neho komponent zasadiť. Tá jednoducho povedané nepasuje.
Vzor Adapter nám komponent obalí naším rozhraním, aplikácia je teda úplne tienené od pôvodného rozhrania komponenty. Kedykoľvek sa toto rozhranie zmení, stačí aktualizovať len Adapter. Vďaka adaptéru môžeme riešiť dokonca aj prípad, kedy sa nám komponent prestane páčiť a vymeníme ju za inú. Vtedy opäť iba opravíme Adapter a program sa zvnútra vôbec nezmení.
Vzor
Vzor je teda akýsi prostredník (spojovník) medzi naším rozhraním a rozhraním komponenty, ktoré je pre aplikáciu neznáme. Tohto prepojenie môžeme dosiahnuť na úrovni objektu alebo na úrovni triedy. Vzor má teda 2 varianty.
Object adapter
Klient
je súčasť nášho systému, ktorá volá naše
rozhranie. Adaptee
je ona komponenta, ktorej rozhranie je
nestabilná, nekompatibilné alebo skrátka nechceme, aby na ňom naše
aplikácia bola závislá. Naša rozhranie je definované v triede
Adapter
, ktorá zaisťuje transformáciu metód od
Klient
a do Adaptee
. Adapter
môže byť
iba spojovník a volať len inak pomenované metódy. Alebo môže obsahovať
jednoduchú logiku. Ako príklad si môžeme predstaviť, že voláme metódu
Vloz(tabulka, pole)
, ktorá sa preloží ako
DatabazovyDotaz('INSERT INTO tabulka VALUES hodnota1, hodnota2...')
.
Pole sa transformovalo na jediný parameter a ten je odovzdaný
Adaptee
.
Vidíme, že Klient
a Adaptee sú prepojené pomocou objektu
Adapter
.
Možná modifikácie
Vzor môžeme vylepšiť pridaním abstraktné triedy Cil
.
Adapter
teraz dedí z abstraktné triedy Cil
.
Zmysel abstraktné triedy je ten, aby sme mohli Adapter
ľahšie
vymeniť za iný a boli si istí, že sme zachovali kompatibilitu. Rovnako tak
môže byť Cil len interface.
Class Adapter
Class adapter je menej používaný variant a to preto, že spolieha na
skutočnosť, že triedu Adaptee
možno dediť. Výsledný adapter
je trieda zdedená z Cil
a Adapter
. Cil
bude samozrejme interface, aby bola viacnásobná dedičnosť možná. Tiež
strácame možnosť pracovať zároveň s potomkami Adaptee
, čo by
u Object adaptéru fungovalo (pretože potomok poskytuje rovnaké rozhranie, ako
predok). Výhodou však je, že môžeme prepísať niektoré metódy
Adaptee
.
Záverom
Wrappery sa často stavajú okolo databáz (možno potom vymeniť databáze bez jedinej zmeny v našej aplikácii) alebo okolo webových služieb, ktoré majú často zložitá API.