← Повернутись до блогу

Адаптер

March 2026 1 хвилина на читання 33062 перегляди

Патерн адаптер відноситься до структурних патернів і потрібен для того, аби зробити можливою роботу двох несумісних систем без переписування жодної з них.

Якщо вам потрібна асоціація, то “впіхнуть нєвпіхуємоє” може бути гарною.

Приклад з життя

Гарним прикладом може бути ситуація. Уявіть, ви сидите в барі, раптом бачите привабливого хлопця за сусіднім столом. Наважуєтесь до нього підійти і заговорити… Але розумієте що він говорить лише французькою. А ви ні. Які у нас є опції?

  1. Вивчити французьку;
  2. Знайти іншого співрозмовника. А якщо жоден не підходить, можна взяти телефон, ввімкнути перекладач і косо-криво поговорити кожен своєю мовою.

Перекладач в цьому випадку відіграють роль адаптера. Його використання дозволило вам вирішити проблему не міняючи ні співрозмовника ні вас.

Відповідно, якби ми програмували такий приклад, це б мало десь такий вигляд:

<?php

class UkrainianGuy
{
    public function say(string $message): string
    {
        return $message;
    }
}

class FrenchGuy
{
    public function dire(string $message): string
    {
        return $message;
    }
}

interface ConversationInterface
{
    public function say(string $message): string;
}

class GoogleTranslateAdapter implements ConversationInterface
{
    public function __construct(
        private FrenchGuy $frenchGuy
    ) {}

    public function say(string $message): string
    {
        $translated = $this->translateToFrench($message);
        return $this->frenchGuy->dire($translated);
    }

    private function translateToFrench(string $message): string
    {
        return "*(перекладено французькою)*: " . $message;
    }
}

// --- Використання ---

$ukrainianGuy = new UkrainianGuy();
$frenchGuy = new FrenchGuy();
$translator = new GoogleTranslateAdapter($frenchGuy);

$message = $ukrainianGuy->say("Привіт! Ти тут один?");
echo $translator->say($message);

Ролі: UkrainianGuy — клієнт. Той, хто ініціює спілкування. Не змінюється FrenchGuy — adaptee (той, кого адаптують). Існуючий клас з несумісним інтерфейсом. Теж не змінюється ConversationInterface — цільовий інтерфейс. Те, як клієнт хоче спілкуватись — через say() GoogleTranslateAdapter — власне адаптер. Реалізує ConversationInterface, але всередині делегує виклик до FrenchGuy::dire()

Коли використовувати?

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

2018–2025 (c) Списуй але не один в один