190 likes | 298 Views
A dapter. Autor: Milan Šafárik. Úvod. Tento vzor patrí do skupiny Structural Patterns . Používa sa aj označenie Wrapper .
E N D
Adapter Autor: Milan Šafárik
Úvod • Tento vzor patrí do skupiny StructuralPatterns. • Používa sa aj označenie Wrapper. • Účelom tohto vzoru je previesť rozhranie triedy do rozhrania, ktoré client očakáva.Adapterumožňuje spoluprácu medzi triedami, ktoré majú nekompatibilné rozhrania.
Príklad z reálneho sveta Zásuvky majú v rôznych krajinách iné tvary a napätia. Ak chceme, aby naše zariadenie spolupracovalo s inou zásuvkou, potrebujeme adaptér.
Využitie • Adapter sa často používa v databázových aplikáciách (je možné vymeniť databázu bez veľkých zmien v aplikácii) alebo v oblasti webových služieb, ktoré majú často komplikované API. • Využitie na zaistenie kompatibility. Napríklad chceme nové triedy, ktoré poskytuje knižnica Swing, ale existuje mnoho klientov, ktorí využívajú staršiu verziu grafiky.
Konkrétny príklad • Majme grafický editor. Rozhranie pre grafické objekty je definované ako abstraktná trieda Shape a má rôzne podtriedy (LineShape, PolygonShape). Chceme ďalšiu podtriedu TextShape, na zobrazenie a editáciu textu. • Máme toolkit, ktorý poskytuje triedu TextView, ktorá zobrazuje a edituje text. V ideálnom prípade by sme chceli použiť TextView na implementovanie triedy textShape. • Toolkit ale nebol navrhnutý na spoluprácu s Shape triedami.
Príklad Ako môže TextView fungovať v aplikácii, kde sa očakávajú triedy s rozdielnym a nekompatibilným rozhraním? Mohli by sme zmeniť TextView triedu aby zodpovedala Shape rozhraniu. Ale ak nemáme zdrojový kód, nepôjde to.
Riešenie Môžeme definovať TextShape tak, že adaptuje TextView rozhranie na Shape rozhranie. Máme možnosti: • Odvodenie novej triedy od nevyhovujúcej (dedenie) a pridanie metod, ktoré zaistia implementáciu požadovaného rozhrania (classadapter). • Vloženie delegácie na triedu Adaptee do Adapteru a delegovanie požiadaviek na metódy Adaptee objektu. (objectadapter).
Uplatnenie • Ak chceme použiť existujúcu triedu, a jej rozhranie nezodpovedá tomu, ktoré potrebujeme. • Ak chceme vytvoriť znovu použiteľnú triedu, ktorá spolupracuje s nesúvisiacimi triedami. To znamená s triedami, ktoré nemusia mať kompatibilné rozhrania. • (objekt verzia) Ak musíme použiť niekoľko existujúcich podtried, ale je nepraktické adaptovať ich rozhranie pre každú zvlášť. Objekt Adapter môže adaptovať rozhranie jeho rodičovskej triedy.
Štruktúra Class verzia využíva viacnásobnú dedičnosť na prispôsobenie jedného rozhrania na druhé.
Štruktúra Object verzia závisí na zložení objektu:
Účastníci • Target – Definuje doménovo špecifické rozhranie, ktoré Client používa. • Client - Spolupracuje s objektami podľa Target rozhrania. • Adaptee – Definuje existujúce rozhranie, ktoré potrebuje adaptovať. • Adapter – Prispôsobí rozhranie Adaptee na Target rozhranie.
Následky (Class verzia) • Adaptee prispôsobujeme na Target viazanosťou ku konkrétnej Adapter triede. Následkom toho trieda Adapter nebude fungovať ak chceme adaptovať triedu a všetky jej podtriedy. • Adapter môže prepísať časť Adaptee správania, pretože Adapter je podtriedou Adaptee. • Zavádza iba jeden objekt a žiadne ďalšie veci nie sú potrebné dostať sa k Adaptee.
Následky (Object verzia) • Umožňuje jednému Adapter fungovať s viacerými Adaptee. Tým sa myslí trieda Adaptee a všetky jej podtriedy. Adapter môže tiež pridať metódu všetkým Adaptee naraz. • Je náročnejšie prepísať správanie Adaptee. Na to je potrebná podtrieda Adaptee a spraviť do podtriedy referenciu na Adapter.
Reálne aplikácie • V jave máme mnoho prvkov, ktoré sú založené na Adapter vzoru. Jedná sa napríklad o WindowAdapter, ComponentAdapter, MouseAdapter, KeyAdapter a iné. • RMI – Spôsob umožnenia komunikácie medzi objektmi z iných adresných priestorov. RemoteAdapter sprístupňuje vzdialenému klientovi metódy lokálnej triedy.
Ukážkový kód public interface Target { public void newRequest(); } publicclass Adaptee { publicvoidoldRequest() { // ... } }
Ukážkový kód public class Adapter implements Target { private Adaptee adaptee; public Adapter() { this.adaptee = new Adaptee(); } @Override public void newRequest() { this.adaptee.oldRequest(); } }
Ukážkový kód public static void main(String[] args) { Target adapter = new Adapter(); adapter.newRequest(); }