Adaptér (návrhový vzor)

Návrhový vzor Adaptér (niekedy nazývaný aj Wrapper) sa používa pri práci so službou (komponentom, aplikáciou a pod.), ktorá má nestabilné alebo s aplikáciou nekompatibilné rozhranie. Umožňuje komponentu obaliť vlastným rozhraním a tak aplikáciu zbaviť závislosti od pôvodného rozhrania. Adaptér je teda forma zmeny rozhrania triedy na rozhranie iné. Zabezpečuje spoluprácu medzi triedami, ktoré by vzhľadom na rozdielne rozhrania neboli schopné spolupracovať. Aplikácia vzoru spočíva vo vložení triedy adaptéru medzi tieto dve triedy.

Motivácia
Jedna z motivácií, kedy a prečo používať návrhový vzor adaptér je nasledujúca. Predstavme si, že chceme alebo musíme pracovať s komponentom, službou alebo inou aplikáciou, ktorej tvorcovia stále menia rozhranie. My túto službu používame na viacerých miestach v aplikácii a pri každej úprave rozhrania tejto služby musíme kód našej aplikácie na viacerých miestach prepisovať. Podobný problém môže tiež nastať, keď máme v aplikácii už pripravené nejaké rozhranie a chceme do nej vložiť novú službu či komponent, ktorý „nepasuje“. Vzor adaptér komponentu obalí naším rozhraním a aplikácia sa tak stane ako keby nezávislá od pôvodného rozhrania komponentu. Kedykoľvek sa toto rozhranie zmení, stačí len aktualizovať adaptér.

V jazyku Java sa s príkladom adaptéra ako návrhového vzoru môžeme stretnúť pri práci s tzv. obaľovacími triedami, ktoré sú často označované ako wrapper, z čoho plynie aj druhý názov používaný v súvislosti s týmto návrhovým vzorom. Tieto wrappery prispôsobujú rozhranie primitívnych dátových typov, aby s nimi bolo zaobchádzané ako s objektovými typmi tak, že primitívny dátový typ obalia adaptérom, ktorý implementuje požadované vlastnosti objektového typu.

Implementácia
Návrhový vzor adaptér je akýsi prostredník medzi naším rozhraním a rozhraním, s ktorým chceme pracovať a je pre nás neznáme alebo nekompatibilné. Adaptér môžeme vzhľadom na jeho implementáciu jednoducho rozdeliť na adaptér objektu a adaptér triedy.
Adaptér objektu
rám|stred|Adaptér objektu
V tomto prípade je klient súčasťou nášho systému, ktorý volá naše rozhranie, ktoré je definované v triede Adapter, ktorá zabezpečuje transformáciu metód medzi triedami Klient a Adaptee. Adaptee je služba (komponent, aplikácia a pod.), ktorej rozhranie je nestabilné, nekompatibilné alebo jednoducho chceme, aby na ňom naša aplikácia nebola závislá.

Táto implementácia sa často vylepšuje pridaním abstraktnej triedy Cieľ. Adapter dedí z abstraktnej triedy Cieľ. Aplikácia abstraktnej triedy nám umožňuje vymeniť triedu Adapter za inú s tým, že sa zachová kompatibilita. Trieda Cieľ môže byť len interface. 
rám|stred|Adaptér objektu - modifikácia
Adaptér triedy
Tento typ implementácie sa používa menej často, pretože spolieha na to, že triedu Adaptee je možné dediť. Výsledný adaptér je trieda zdedená z tried Cieľ a Adaptér. Trieda Cieľ bude interface, aby bola umožnená viacnásobná dedičnosť.
rám|stred|Adaptér triedy
Príklad použitia
Predstavme si, že účtovnícka aplikácia potrebuje prepojenie s aplikáciou, ktorá spravuje personálne informácie, s cieľom výmeniť údaje o zamestnancoch. Každá z nich má svoje vlastné rozhranie a implementáciu. Okrem toho, citlivé údaje o osobách sú uložené v rôznych formátoch v každom systéme. Použitím vzoru Adaptér môžeme vytvoriť spoločné rozhranie medzi týmito dvoma aplikáciami, ktoré im umožňuje medzi sebou komunikovať pomocou pôvodného správania a zároveň je aj schopné transformovať rôzne formáty údajov.
Zhrnutie
Návrhový vzor Adaptér sa používa v situácii, keď je potrebné, aby trieda mala iné rozhranie než to, ktoré práve má.
Adaptér umožňuje spoluprácu triedam, ktoré by inak nespolupracovali vďaka rozdielnemu rozhraniu.
Adaptér je možné vzhľadom na použitú implementáciu klasifikovať na adaptér triedy a adaptér objektu.
Literatúra
Pecinovský, R. Návrhové vzory, 1. vyd. Brno: Computer Press, a.s., 2007. ISBN 978-80-251-1582-4.
Gamma, E. and collective of authors. Desigh Patterns: Elements of Reusable Object-Oriented Software. 1 edition. Addison-Wesley Professional, 1994. ISBN 978-0201633610.