Adapter jest wzorcem, którego zadaniem jest konwersja jednego inteface’u w drugi, co pozwoli na wykorzystanie klasy adaptowanej tam, gdzie nie zostało to pierwotnie założone.

Wyobraźmy sobie, że kupujemy nowy monitor. Okazuje się, że monitor ma kabel który nie pasuje do naszej karty graficznej. Pierwszym skojarzeniem jest użycie odpowiedniej ‚przejściówki’ co pozwoli na podłączenie wtyczki nowego typu do gniazda starego typu. Tak działa właśnie adapter.

Przykład:

Posiadamy program pilota, który steruje całym naszym sprzętem w domu m.in. telewizorem. Oto kod pilota i interfejsu telewizora:

Jednak pewnego dnia otrzymujemy całkiem nową, super wypasioną 60-cio calową plazmę, wraz z klasą sterującą. Poniżej kod klasy i interface’u :

Problem w tym, że zarówno do kodu pilota jak i sterowników plazy nie mamy bezpośrednio dostępu. Musimy zatem utworzyć ‚przejściówkę’ która będzie udawać Telewizor, a jednocześnie wykonywać kod plazmy. Są na to dwa sposoby: przez kompozycję (adapter obiektu) i przez dzedziczenie (adapter klas).

Adapter przez kompozycję:

Adapter przez dziedziczenie:

Różnica jest subtelna. W pierwszym przypadku metody delegowane są do innego obiektu, w drugim wykonywane są metody na rzecz tego samego obiektu. Należy zwrócić uwagę, że adapter obiektu ma możliwość emulowania klas pochodnych adaptowanego interface’u – adapter klas nie ma takiej możliwości. Drugim ważnym elementem jest napisywanie metod. Oba adaptery nadpisują metody interface’u, jednak adapter klas ma dostęp do niezmienionych pozostałych metod emulowanej klasy.

Oba przypadki pozwalają nam na użycie w naszym przypadku ponieważ każdy z tych adapterów implementuje interface ‚Telewizor’.

Diagram klas wzorca Adapter wygląda następująco:

Na diagramie przedstawiony jest adapter przez kompozycję.
.