Ответ
Interactor (Сценарий использования) — это компонент в архитектурах типа Clean Architecture или DDD, который инкапсулирует конкретную бизнес-правило или операцию. Его задача — оркестрировать поток данных между репозиториями (источниками данных) и презентационным слоем, выполняя чистую бизнес-логику.
Ключевые принципы:
- Отделение логики: Interactor не знает о UI (Widgets) или конкретных источниках данных (база данных, API). Он работает с абстракциями (репозиториями).
- Одна ответственность: Каждый интерактор отвечает за одну бизнес-операцию (например, «аутентификация пользователя», «получение списка новостей»).
Пример на Dart (используя пакет flutter_bloc):
// Абстракция репозитория
abstract class AuthRepository {
Future<User> login(String email, String password);
}
// Interactor (часто реализуется как UseCase)
class LoginUseCase {
final AuthRepository _authRepository;
LoginUseCase(this._authRepository);
Future<Either<Failure, User>> execute(LoginParams params) async {
// Валидация параметров (бизнес-правило)
if (!params.isValid) {
return Left(ValidationFailure());
}
// Вызов репозитория и обработка результата
try {
final user = await _authRepository.login(params.email, params.password);
return Right(user);
} on SocketException {
return Left(NetworkFailure());
} on ApiException catch (e) {
return Left(ServerFailure(message: e.message));
}
}
}
// Параметры для инкапсуляции входных данных
class LoginParams {
final String email;
final String password;
LoginParams(this.email, this.password);
bool get isValid => email.isNotEmpty && password.length >= 6;
}
Преимущества: Такой подход делает бизнес-логику независимой, легко тестируемой (можно мокать репозиторий) и переиспользуемой.
Ответ 18+ 🔞
А, ну вот, опять про эти ваши интеракторы. Слушай, давай я тебе на пальцах объясню, а то в этих умных книжках такое понапишут, что сам потом нихуя не поймёшь, что к чему.
Представь себе, что у тебя есть бармен. Это и есть интерактор, ёпта. Его работа — не мыть стаканы (это репозиторий) и не улыбаться гостям (это UI). Его работа — сделать тебе конкретный коктейль по правилам. Ты говоришь: «Дай-ка „Отвёртку“». Он не бежит сам к холодильнику за апельсиновым соком — он орёт на грузчика (репозиторий): «Вася, дай сока!». Получает сок, берёт водку с полки, смешивает в нужной пропорции (это его бизнес-правило, блядь!) и отдаёт тебе готовое. Всё. Он — центр управления полётами для одной операции.
В чём соль, а?
- Он тупой как пробка в одном, но гениальный в другом. Он не знает, откуда Вася взял сок — из картонной коробки или выжал апельсины. Ему похуй. Его дело — знать рецепт. Это и есть отделение логики.
- Один заказ — один бармен. Не будет же один мужик одновременно жарить стейк, мешать коктейль и мыть пол. Так и тут: один интерактор — одна операция. «Залогинить пользователя» или «получить список друзей». И всё.
Смотри, как это выглядит в коде, тут всё честно:
// Это типа контракт с грузчиком Васей. Просто говорим, что он должен уметь давать сок.
abstract class AuthRepository {
Future<User> login(String email, String password);
}
// А вот и наш бармен, специалист по коктейлю "Логин".
class LoginUseCase {
final AuthRepository _authRepository; // Он знает, что есть Вася, который может дать данные.
LoginUseCase(this._authRepository);
Future<Either<Failure, User>> execute(LoginParams params) async {
// Сначала он проверяет твои ингредиенты. Ты ему воду из лужи принёс?
if (!params.isValid) {
return Left(ValidationFailure()); // Нахуй такую «Отвёртку», клиент не прав.
}
// Если норм, начинает работать.
try {
// Орёт Васе: «Неси данные!»
final user = await _authRepository.login(params.email, params.password);
return Right(user); // Вуаля, держи свой коктейль, доволен.
} on SocketException {
return Left(NetworkFailure()); // А Вася в сортире, связи нет. Пиздец.
} on ApiException catch (e) {
return Left(ServerFailure(message: e.message)); // А на складе пожар, сервер сгорел.
}
}
}
// Это просто паспорт для твоих ингредиентов, чтобы в бармена не горстями соль кидать.
class LoginParams {
final String email;
final String password;
LoginParams(this.email, this.password);
bool get isValid => email.isNotEmpty && password.length >= 6; // Правило: меньше 6 символов — это не пароль, а издевательство.
}
И что в итоге, ядрёна вошь? А то, что теперь твою бизнес-логику (рецепт коктейля) можно тестировать отдельно от всего. Подсовываешь бармену муляж Васю, который всегда приносит тухлый сок, и смотришь, как бармен правильно скажет «клиент, иди нахуй». Всё независимо, переиспользуемо и не привязано ни к Flutter, ни к базе данных. Красота, доверия ебать ноль ко всему остальному, но зато своя работа сделана на пятёрочку.