Adapter

Przeznaczenie

  • Dokonuje konwersji interfejsu danej klasy do postaci zgodnej z oczekiwaniami klienta

  • Pozwala na wzajemną współpracę klas, które ze względu na niekompatybilne interfejsy wcześniej nie mogły ze sobą współpracować

Kontekst

  • Interfejs wymagany przez klienta i interfejs klasy dostarczającej implementację nie są ze sobą zgodne

Problem

  • Chcemy wykorzystać istniejącą klasę, a jej interfejs nie odpowiada temu, którego potrzebujemy

Implementacje wzorca Adapter

Istnieją następujące implementacje wzorca Adapter:

  • Adapter klas

  • Adapter obiektów

  • Adapter dwukierunkowy

Adapter klas

_images/Adapter_Klas.png

Uczestnicy:

  • Target – definiuje specyficzny dla danej dziedziny interfejs używany przez klienta

  • Client – współpracuje z obiektami dostosowanymi do interfejsu Target

  • Adaptee – definiuje istniejący interfejs, który wymaga zaadoptowania

  • Adapter – adaptuje interfejs Adaptee do interfejsu Target

Konsekwencje:

  • Adaptuje Adaptee do Target, dostosowując się do klasy konkretnej Adaptee - nie będzie więc działał wtedy, gdy będziemy chcieli zaadaptować klasę oraz jej wszystkie podklasy

  • Umożliwia klasie Adapter przedefiniowanie części zachowania AdapteeAdapter jest jej klasą pochodną

  • Wprowadza tylko jeden obiekt, aby dostać się do adaptowanego

Adapter obiektów

_images/Adapter_Obiektow.png

Uczestnicy:

  • Target – definiuje specyficzny dla danej dziedziny interfejs używany przez klienta

  • Client – współpracuje z obiektami dostosowanymi do interfejsu Target

  • Adaptee – definiuje istniejący interfejs, który wymaga zaadoptowania

  • Adapter – adaptuje interfejs Adaptee do interfejsu Target

Konsekwencje:

  • Umożliwia jednemu adapterowi działanie z wieloma adaptowanymi – z samą klasą Adaptee oraz jej wszystkimi podklasami

  • Utrudnia przedefiniowanie zachowania adaptowanego (Adaptee) - wymaga w tym celu tworzenia podklas adaptowanego i odwoływania się Adaptera do nich, a nie do samego adaptowanego (Adaptee)

Adapter dwukierunkowy

Adaptery dwukierunkowe zapewniają przezroczystość. Są szczególnie przydatne w sytuacji, gdy dwóch różnych klientów musi inaczej widzieć ten sam obiekt.

Implementacja - dziedziczenie publiczne po dwóch klasach: Target i Adaptee

Pokrewne wzorce

  1. Bridge:

  • ma strukturę podobną do adaptera obiektów, ale inne przeznaczenie,

  • ma oddzielać interfejs od implementacji, tak aby mogły być zmieniane niezależnie.

  1. Decorator – ulepsza inny obiekt, nie zmieniając jego interfejsu.

  2. Proxy – definiuje reprezentanta lub substytut innego obiektu i nie zmienia interfejsu.

Podsumowanie

Rola adaptera polega na zmianie interfejsu istniejącego obiektu. Klasy nie związane ze sobą mogą współpracować pomimo niezgodnych interfejsów.