Читати книгу - "Занурення в патерни проектування, Олександр Швець"
Шрифт:
Інтервал:
Добавити в закладку:
Ви можете створити адаптер. Це об’єкт-перекладач, який трансформує інтерфейс або дані одного об’єкта таким чином, щоб він став зрозумілим іншому об’єкту.
Адаптер загортає один з об’єктів так, що інший об’єкт навіть не підозрює про існування першого. Наприклад, об’єкт, що працює в метричній системі вимірювання, можна «обгорнути» адаптером, який буде конвертувати дані у фути.
Адаптери можуть не тільки конвертувати дані з одного формату в інший, але й допомагати об’єктам із різними інтерфейсами працювати разом. Це виглядає так:
Адаптер має інтерфейс, сумісний з одним із об’єктів. Тому цей об’єкт може вільно викликати методи адаптера. Адаптер отримує ці виклики та перенаправляє їх іншому об’єкту, але вже в тому форматі та послідовності, які є зрозумілими для цього об’єкта.Іноді вдається створити навіть двосторонній адаптер, який може працювати в обох напрямках.
Програма може працювати зі сторонньою бібліотекою через адаптер.
Таким чином, для програми біржових котирувань ви могли б створити клас XML_To_JSON_Adapter, який би обгортав об’єкт того чи іншого класу бібліотеки аналітики. Ваш код посилав би адаптеру запити у форматі XML, а адаптер спочатку б транслював вхідні дані у формат JSON, а потім передавав їх методам загорнутого об’єкта аналітики.
Аналогія з життяВміст валіз до й після поїздки за кордон.
Під час вашої першої подорожі за кордон спроба зарядити ноутбук може стати неприємним сюрпризом, тому що стандарти розеток у багатьох країнах різняться. Ваша європейська зарядка стане непотрібом у США без спеціального адаптера, що дозволяє під’єднуватися до розетки іншого типу.
Структура Адаптер об’єктівЦя реалізація використовує агрегацію: об’єкт адаптера «загортає», тобто містить посилання на службовий об’єкт. Такий підхід працює в усіх мовах програмування.
Клієнт — це клас, який містить існуючу бізнес-логіку програми.
Клієнтський інтерфейс описує протокол, через який клієнт може працювати з іншими класами.
Сервіс — це який-небудь корисний клас, зазвичай сторонній. Клієнт не може використовувати цей клас безпосередньо, оскільки сервіс має незрозумілий йому інтерфейс.
Адаптер — це клас, який може одночасно працювати і з клієнтом, і з сервісом. Він реалізує клієнтський інтерфейс і містить посилання на об’єкт сервісу. Адаптер отримує виклики від клієнта через методи клієнтського інтерфейсу, а потім конвертує їх у виклики методів загорнутого об’єкта в потрібному форматі.
Працюючи з адаптером через інтерфейс, клієнт не прив’язується до конкретного класу адаптера. Завдяки цьому ви можете додавати до програми нові види адаптерів, незалежно від клієнтського коду. Це може стати в нагоді, якщо інтерфейс сервісу раптом зміниться, наприклад, після виходу нової версії сторонньої бібліотеки.
Адаптер класівЦя реалізація базується на спадкуванні: адаптер успадковує обидва інтерфейси одночасно. Такий підхід можливий тільки в мовах, які підтримують множинне спадкування, наприклад у C++.
Адаптер класів не потребує вкладеного об’єкта, тому що він може одночасно успадкувати й частину існуючого класу, й частину класу сервісу.
ПсевдокодУ цьому жартівливому прикладі Адаптер перетворює один інтерфейс на інший, дозволяючи поєднувати квадратні кілочки та круглі отвори.
Приклад адаптації квадратних кілочків та круглих отворів.
Адаптер обчислює найменший радіус кола, у яке можна вписати квадратний кілочок, і подає його як круглий кілочок із цим радіусом.
// Класи з сумісними інтерфейсами: КруглийОтвір та// КруглийКілочок.
class RoundHole is
constructor RoundHole(radius) { ... }
method getRadius() is
// Повернути радіус отвору.
method fits(peg: RoundPeg) is
return this.getRadius() >= peg.getRadius()
class RoundPeg is
constructor RoundPeg(radius) { ... }
method getRadius() is
// Повернути радіус круглого кілочка.
// Застарілий несумісний клас: КвадратнийКілочок.
class SquarePeg is
constructor SquarePeg(width) { ... }
method getWidth() is
// Повернути ширину квадратного кілочка.
// Адаптер дозволяє використовувати квадратні кілочки й круглі
// отвори разом.
class SquarePegAdapter extends RoundPeg is
private field peg: SquarePeg
constructor SquarePegAdapter(peg: SquarePeg) is
this.peg = peg
method getRadius() is
// Обчислити половину діагоналі квадратного кілочка за
// теоремою Піфагора.
return peg.getWidth() * Math.sqrt(2) / 2
// Десь у клієнтському програмному коді.
hole = new RoundHole(5)
rpeg = new RoundPeg(5)
hole.fits(rpeg) // TRUE
small_sqpeg = new SquarePeg(5)
large_sqpeg = new SquarePeg(10)
hole.fits(small_sqpeg) // Помилка компіляції, несумісні типи.
small_sqpeg_adapter = new SquarePegAdapter(small_sqpeg)
large_sqpeg_adapter = new SquarePegAdapter(large_sqpeg)
hole.fits(small_sqpeg_adapter) // TRUE
hole.fits(large_sqpeg_adapter) // FALSE Застосування
Якщо ви хочете використати сторонній клас, але його
!Увага!
Сайт зберігає кукі вашого браузера. Ви зможете в будь-який момент зробити закладку та продовжити читання книги «Занурення в патерни проектування, Олександр Швець», після закриття браузера.