Адаптер (шаблон проєктування)

Адаптер, Adapter — структурний шаблон проєктування, призначений для організації використання функцій об'єкту, недоступного для модифікації, через спеціально створений інтерфейс.

Призначення ред.

Адаптує інтерфейс одного класу в інший, очікуваний клієнтом. Адаптер забезпечує роботу класів з несумісними інтерфейсами, та найчастіше застосовується тоді, коли система підтримує необхідні дані і поведінку, але має невідповідний інтерфейс.

Застосування ред.

Адаптер передбачає створення класу-оболонки з необхідним інтерфейсом.

Структура ред.

 
UML діаграма, що ілюструє структуру шаблону проєктування Адаптер (з використанням множинного наслідування)

Учасники ред.

Клас Adapter приводить інтерфейс класу Adaptee у відповідність з інтерфейсом класу Target (спадкоємцем якого є Adapter). Це дозволяє об'єктові Client використовувати об'єкт Adaptee так, немов він є екземпляром класу Target.

Наслідки ред.

Шаблон Адаптер дозволяє включати вже наявні об'єкти в нові об'єктні структури, незалежно від відмінностей в їхніх інтерфейсах.

Переваги та недоліки ред.

Переваги ред.

  • Допомагає досягти багаторазового використання та гнучкості.
  • Клас клієнта не ускладнюється необхідністю використовувати інший інтерфейс і може використовувати поліморфізм для обміну між різними реалізаціями адаптерів.

Недоліки ред.

  • Всі запити пересилаються, тому спостерігається незначне збільшення накладних витрат.
  • Іноді багато адаптацій потрібні по ланцюгу адаптера, щоб досягти потрібного типу.

Зв'язок з іншими патернами ред.

  • Фасад створює новий інтерфейс доступу, адаптер — використовує старий

Реалізація ред.

Інтерфейс класу Adaptee, тобто того, який адаптується, приводиться у відповідність з новими вимогами класу Target, а виклики його методів перетворяться у виклики методів класу Target.

Шаблон Адаптер для адаптації інтерфейсу методу/ів Adaptee до інтерфейсу Target в Adapter можна реалізувати як мінімум двома способами: використовуючи композицію+успадкування (Адаптер об'єкта), або використовуючи множинне успадкування (Адаптер класу).

  • Адаптер об'єкта: Adapter наслідує інтерфейс від Target (успадкування) та містить примірник (здебільшого як вказівник) класу Adaptee (композиція) і делегує виклики своїх методів (які збігаються з інтерфейсом Target) до Adaptee
  • Адаптер класу: Adapter наслідує інтерфейси обох класів Target та Adaptee (множинне успадкування). В ООП-мовах, які не підтримують множинне успадкування, реалізація цього варіанту адаптера дещо складніша (наприклад в Java за допомогою інтерфейсів).

C++ ред.

Java ред.

Зауваження і коментарі ред.

Шаблон Адаптер дозволяє в процесі проєктування не брати до уваги можливі відмінності в інтерфейсах вже наявних класів. Якщо є клас, що володіє необхідними методами і властивостями (принаймні, концептуально), то при необхідності завжди можна скористатися шаблоном Адаптер для приведення його інтерфейсу до потрібного вигляду.

Більш прийнятним є адаптер об'єкта, в якому використовується композиція+успадкування, оскільки це більш відповідає правилу "надавайте перевагу композиції, а не успадкуванню". Цей адаптер можна використовувати тільки односторонньо — як заміну для Target. Однак, у випадку, коли ми створюємо двосторонній адаптер, або ж адаптер, який адаптує одночасно кілька Adaptee класів, слід надавати перевагу шаблону адаптера класу. Також адаптер класу дозволяє більш ефективно використовувати вже реалізований код з Target та Adaptee. Однак недоліки адаптера класу випливають з множинного успадкування, коли зміни в деяких базових класах викликають непередбачливі зміни в похідних, а особливо, коли це відбувається одночасно в кількох успадкованих адаптером класах.

Близьким Адаптеру є шаблон Фасад, не завжди можна відрізнити один від другого. Різниця полягає в тому, що шаблон Фасад призначений для спрощення інтерфейсу і створює новий інтерфейс, тоді як шаблон Адаптер використовує з обох сторін інтерфейси, які є в наявності, і забезпечує їх функціювання.

Відомі застосування ред.

Типовим прикладом використання шаблону Адаптер можна назвати створення класів, що приводять до єдиного інтерфейсу функції мови PHP що забезпечують доступ до різних СУБД[1].

Примітки ред.

  1. В мові PHP доступ до СУБД реалізований у вигляді набору функцій, для кожної СУБД вони мають різні найменування і, іноді, різний набір використовуваних параметрів, що приводить до значних проблем при переході з однією СУБД на іншу, якщо такий перехід наперед не забезпечений використанням шаблону Адаптер.

Джерела ред.

Література ред.

Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М. : «Вильямс», 2002. — 288 с. — ISBN 0-201-71594-5.