← Назад к вопросам

Что такое паттерн Адаптер (Adapter)?

2.3 Middle🔥 132 комментариев
#ООП и паттерны

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Паттерн Адаптер (Adapter)

Adapter Pattern — это структурный паттерн проектирования, который позволяет объектам с несовместимыми интерфейсами работать вместе. Адаптер выступает переходником, трансформирующим интерфейс одного класса в интерфейс, который ожидает клиент.

Главная идея

Представь, что у тебя есть класс LegacyDatabase, который имеет метод fetchData(), а новый код ожидает интерфейс DataSource с методом getData(). Вместо изменения LegacyDatabase (что может сломать другой код), создаёшь Адаптер:

// Старый интерфейс (не можем менять)
class LegacyDatabase {
  String fetchData() => "Data from legacy DB";
}

// Новый интерфейс, который ожидает наш код
abstract class DataSource {
  Future<String> getData();
}

// Адаптер: преобразует старый интерфейс в новый
class DatabaseAdapter extends DataSource {
  final LegacyDatabase _database;
  
  DatabaseAdapter(this._database);
  
  @override
  Future<String> getData() async {
    return _database.fetchData();
  }
}

// Использование
void main() async {
  final legacy = LegacyDatabase();
  final adapter = DatabaseAdapter(legacy);
  
  final data = await adapter.getData(); // Работает!
  print(data);
}

Два вида адаптеров

Class Adapter (через наследование)

Адаптер наследует старый класс и реализует новый интерфейс:

class DatabaseAdapter extends LegacyDatabase implements DataSource {
  @override
  Future<String> getData() async {
    return fetchData(); // Вызываем метод из LegacyDatabase
  }
}

Object Adapter (через композицию)

Адаптер содержит объект старого класса (рекомендуется):

class DatabaseAdapter implements DataSource {
  final LegacyDatabase _database;
  
  DatabaseAdapter(this._database);
  
  @override
  Future<String> getData() async {
    return _database.fetchData();
  }
}

Практические примеры

Пример 1: Адаптер для API

// Старый API (сторонний пакет)
class RestClient {
  String get(String url) {
    return '{"status": "ok"}';
  }
}

// Новый интерфейс приложения
abstract class HttpClient {
  Future<Map<String, dynamic>> getJson(String url);
}

// Адаптер
class RestClientAdapter implements HttpClient {
  final RestClient _client;
  
  RestClientAdapter(this._client);
  
  @override
  Future<Map<String, dynamic>> getJson(String url) async {
    final response = await Future(() => _client.get(url));
    return jsonDecode(response);
  }
}

Пример 2: Адаптер для UI компонентов

// Старый компонент
class OldButton {
  void onPressed() => print("Clicked");
}

// Новый интерфейс
abstract class Button {
  void onTap();
}

// Адаптер
class OldButtonAdapter implements Button {
  final OldButton _button;
  
  OldButtonAdapter(this._button);
  
  @override
  void onTap() => _button.onPressed();
}

Пример 3: Адаптер для коллекций

// Старый формат данных
class UserList {
  List<dynamic> getUserIds() => [1, 2, 3];
}

// Новый интерфейс
abstract class UserRepository {
  Future<List<int>> fetchUserIds();
}

// Адаптер
class UserListAdapter implements UserRepository {
  final UserList _userList;
  
  UserListAdapter(this._userList);
  
  @override
  Future<List<int>> fetchUserIds() async {
    return _userList.getUserIds().cast<int>();
  }
}

Когда использовать Adapter

  • Интеграция legacy кода — подключение старого кода к новой архитектуре
  • Работа со сторонними библиотеками — если интерфейс не совпадает с ожиданиями
  • Тестирование — создание mock-адаптеров для unit тестов
  • Миграция кода — постепенный переход с одного интерфейса на другой

Плюсы и минусы

Плюсы:

  • Не нужно менять исходный класс
  • Разделяет ответственность
  • Позволяет работать с несовместимыми интерфейсами

Минусы:

  • Добавляет уровень абстракции
  • Может замедлить производительность
  • Усложняет кодовую базу

Адаптер — это мощный инструмент для интеграции несовместимого кода в приложение Flutter.

Что такое паттерн Адаптер (Adapter)? | PrepBro