Adapter design pattern

Подобно на Decorator pattern, Adapter pattern също се използва когато имаме нужда на вече готов обект (т.е. runtime) и трябва да му променим поведението. С разликата, че Decorator добавя функционалност, а Adapter я променя и напасва.

Може и да добавя логика, но идеята, the intention е да напасне, не да разшири функционалността.

Както казахме, много Design patterns страшно си приличат и застъпват, but the intention, the reason for using them, is what makes the difference which one to choose, not the concrete implementation.

Тоест, Adapter design pattern трябва да се използва когато искаме от класът който ще адаптираме това което ни трябва, без да му добавяме още логика, но просто не можем да го използваме директно.

Например, малките адаптери за различните ел. контакти когато пътуваме в чужбина са точно пример за Adapter design pattern.

Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.

Как най-просто става това?

Като например в Adapter класът инджектнем като property (HAS-A) обектът, който ще адаптираме (нека го наричаме Adaptee), и който (Adapter) ще използва неговите (на Adaptee) публични методи в своите методи, за да зададе друга логика, като използва и променя логиката от Аdaptee (инджектнатият) обект.

И на практика, т.н. Client ще може да използва методите на Adapteе, но не директно, а през Adapter. Демек, съответният метод на Adaptee, който е нужен на Client, той (Client) ще вика съответният всъщност на Adapter, а Adapter ще вика съответният на Adaptee като преди това ще извършва своята работа по „адаптирането“.

„The adapter design pattern allows otherwise incompatible classes to work together by converting the interface of one class into an interface expected by the clients.“

Toва ще рече, че за да приложим на практика този Design pattern, трябва да имаме пълно познание за интерфейсът на адаптирания клас (Adaptee) и също и на Client класът.

На пръв поглед излиза, че Adapter design pattern е нещо доста просто и програмно се състои само от един клас Adapter, който стои между Client и Adaptee и адаптира извикванията към методите на Adaptee. Един клас, толкоз. Сигурно затова някои казват, че този design pattern бил на практика по-скоро един wrapper.

По принцип това е така, най-просто казано идеята на Adapter design pattern е точно такава.

Но сложността идва от начините на реализация.

Дали класът Adapter ще е просто един standalone (напълно независим) клас (т.н. Object Adapter Pattern)?
Или ще наследява адаптираният (т.н. Class Adapter Pattern)?

При Object adapter pattern той (Adapter) съдържа в себе си като пропърти обект от aдаптираният клас и използвайки неговият интерфейс (публичните му методи) извикава съответните методи (на Adaptee). Toзи подход е възможен разбира се, само в случаите, когато Adaptee класът е instantiatable.
Както се разбира, тук имаме composition (HAS-A), не inheritance (IS-A).

При Class аdapter pattern Adapter използва функционалността на Adaptee не по горният начин, a като го наследява, inheritance (IS-A), a не composition(HAS-A).

Литература:

https://en.wikipedia.org/wiki/Adapter_pattern