Когда стоит использовать паттерн Adapter?

«Когда стоит использовать паттерн Adapter?» — вопрос из категории Паттерны, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Я использовал паттерн Адаптер (Adapter) для интеграции сторонних библиотек или унаследованного кода, интерфейс которого не совместим с интерфейсом, ожидаемым в моей системе. Он позволяет работать со старым кодом, не изменяя его.

Типичный пример из моего опыта: нужно было использовать старую библиотеку для работы с графикой (например, с устаревшим API рисования), в то время как основное приложение работало с современным интерфейсом ModernRenderer.

// Интерфейс, который ожидает наша система (Цель)
class ModernRenderer {
public:
    virtual void drawShape(float x, float y, float width, float height) = 0;
};

// Устаревший класс, который нужно адаптировать (Адаптируемый)
class LegacyGraphics {
public:
    void render(int x1, int y1, int x2, int y2) {
        // Старый код рисования прямоугольника
        std::cout << "Legacy draw: (" << x1 << "," << y1 << ") to (" << x2 << "," << y2 << ")n";
    }
};

// Адаптер, наследует цель и содержит адаптируемый объект
class GraphicsAdapter : public ModernRenderer {
    LegacyGraphics* legacyGraphics;
public:
    GraphicsAdapter(LegacyGraphics* lg) : legacyGraphics(lg) {}

    void drawShape(float x, float y, float w, float h) override {
        // Преобразуем новый интерфейс в старый
        legacyGraphics->render(static_cast<int>(x), static_cast<int>(y),
                               static_cast<int>(x + w), static_cast<int>(y + h));
    }
};

// Использование в клиентском коде
int main() {
    LegacyGraphics oldLib;
    GraphicsAdapter adapter(&oldLib);

    // Теперь можно использовать старую библиотеку через новый интерфейс
    ModernRenderer* renderer = &adapter;
    renderer->drawShape(10.5f, 20.5f, 100.0f, 50.0f);
    return 0;
}

Я применяю Adapter, когда нужно повторно использовать проверенный, но устаревший код, и когда изменение его исходников невозможно или нецелесообразно.