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

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

Адаптер, 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.