Wzorzec Adapter zalicza się do strukturalnych wzorców projektowych i pozwala zintegrować ze sobą niekompatybilne systemy, nie naruszając przy tym istniejącej struktury, np: zewnętrzne biblioteki dołączane do programu, nie zgodność wersji platformy programistycznej (frameworka) z danym modułem, interfejsem itp.

Wzorzec ten występuje w dwóch wariantach. Implementacja może odbywać się z wykorzystaniem dziedziczenia lub kompozycji. Ja skupię się tylko na tym drugim, ze względu na większą elastyczność 🙂
 

SCHEMAT WZORCA ADAPTER (wariant z kompozycją)

wzorzec adapter

Źródło: pl.wikipedia.org/wiki/Adapter_(wzorzec_projektowy)

PRZYKŁAD

Załóżmy, że nasz stary system webowy korzysta z bazy danych MySQL oraz sterownika mysqli, do jej obsługi. Do systemu mamy zamiar podpiąć inny podsystem, którego interfejs korzysta z PostgreSQL i sterownika PDO, który jak wiemy umożliwia komunikację z każdym typem bazy 🙂 . Oba systemy są niekompatybilne. Potrzebujemy więc „przejściówki” -adaptera, który rozwiąże ten problem i pozwoli współpracować obu bazom.

Oczywiście najlepszym wyjściem było by przepisanie klasy odpowiedzialnej za połączenie z bazą danych, ale z pewnych względów (załóżmy), nie jest to możliwe i szybszym rozwiązaniem będzie napisanie adaptera.

Na początek zbadajmy „stare” rozwiązanie, z którego korzysta nasz system. Jest to interfejs MysqliConnect i klasa implementująca go – MysqliController.
Interfejs zawiera parametry do połączenia z bazą danych i metodę linkDB(), która nawiązuje połączenie z serwerem.

Metoda linkDB() jest abstrakcyjna, a jej konkretna implementacja jest w poniższej klasie MysqliController:

Niekompatybilny system do komunikacji z każdą bazą danych ma analogiczną strukturę. Interfejs PdoConnect posiada parametry do połączenia z serwerem bazy i definicję metody PdoLinkDb():

Klasa PdoController implementuje interfejs PdoConnect:

Jak dotąd, kod poszczególnych klas jest bardzo prosty i nie wymaga szczegółowych analiz. Teraz, czas na naszego bohatera, czyli adaptera. Od tego momentu musisz się już bardziej skupić 🙂

Klasa adaptera DbAdapter implementuje „stary” interfejs MysqliConnect. Oprócz tego, do kodu dołączamy klasę adaptowaną PdoController. Poprzez typowanie przekazujemy do konstruktora obiekt interfejsu PdoConnect:

Metoda linkDB() (z interfejsu MysqliConnect) implementuje metodę PdoLinkDb() przypisując ją do instancji adaptera. Tak więc, wywołując metodę linkDB() wykonujemy kod metody adaptowanej – PdoLinkDb 🙂 .

Na koniec zapisujemy klasę klienta, która wykona żądania:

Do klasy Client dołączamy adaptera – DbAdapter i klasę adaptowaną – PdoController. Konstruktor najpierw tworzy obiekt klasy adaptowanej: new PdoController(), a następnie adapter: new DbAdapter($this->controller). Adapter pobiera instancję obiektu adaptowanego. Na koniec wywoływana jest metoda linkDB(), a w rzeczywistości kod z PdoLinkDb().
 
PRZYKŁAD na GitHub →