Комментарии (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.