Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Interactor в архитектуре Clean Architecture
Interactor (или Use Case) — это слой бизнес-логики в Clean Architecture, который содержит весь функционал приложения. Interactor не знает о деталях реализации UI или баз данных, он работает с абстрактными интерфейсами.
Слои Clean Architecture
┌─────────────────────────────┐
│ Presentation (UI) │
├─────────────────────────────┤
│ Interactor (Use Case) │ <- Именно здесь
├─────────────────────────────┤
│ Repository (Data Access) │
├─────────────────────────────┤
│ Entity (Domain Models) │
└─────────────────────────────┘
Interactor — это связующее звено между UI и данными.
Структура Interactor
Interactor содержит:
- Входные данные (Input)
- Выходные данные (Output)
- Логику выполнения
// Определяем контракт (interface)
abstract class GetUserInteractor {
Future<void> call(GetUserInput input);
}
// Input — что нужно получить
class GetUserInput {
final String userId;
GetUserInput({required this.userId});
}
// Output — результат (обычно через callback)
abstract class GetUserOutput {
void onSuccess(User user);
void onError(Failure failure);
}
// Реализация Interactor
class GetUserUseCaseImpl implements GetUserInteractor {
final UserRepository repository;
GetUserUseCaseImpl({required this.repository});
@override
Future<void> call(GetUserInput input) async {
try {
// Бизнес-логика: получаем пользователя из репозитория
final user = await repository.getUserById(input.userId);
// Валидация в Interactor
if (user.age < 18) {
return;
}
// Возвращаем результат через presenter
// (presentation слой обрабатывает результат)
} on Exception catch (e) {
// Обработка ошибок
return;
}
}
}
Практический пример: Аутентификация
// Entity — доменная модель
class User {
final String id;
final String email;
final String name;
User({
required this.id,
required this.email,
required this.name,
});
}
// Input для interactor
class LoginInput {
final String email;
final String password;
LoginInput({
required this.email,
required this.password,
});
}
// Output для presenter
abstract class LoginOutput {
void onSuccess(User user);
void onEmailError(String message);
void onPasswordError(String message);
void onServerError(String message);
}
// Interactor (Use Case)
class LoginUseCaseImpl implements LoginUseCase {
final AuthRepository authRepository;
final UserRepository userRepository;
LoginUseCaseImpl({
required this.authRepository,
required this.userRepository,
});
@override
Future<void> call(
LoginInput input,
LoginOutput presenter,
) async {
// Валидация email
if (!_isValidEmail(input.email)) {
presenter.onEmailError('Invalid email format');
return;
}
// Валидация пароля
if (input.password.length < 6) {
presenter.onPasswordError('Password must be at least 6 characters');
return;
}
try {
// Бизнес-логика: аутентификация
final token = await authRepository.authenticate(
input.email,
input.password,
);
// Получаем данные пользователя
final user = await userRepository.getUser(token);
// Возвращаем результат
presenter.onSuccess(user);
} on ServerException catch (e) {
presenter.onServerError(e.message);
} on NetworkException catch (e) {
presenter.onServerError('Network error: check your connection');
}
}
bool _isValidEmail(String email) {
return email.contains('@');
}
}
Использование Interactor в Presenter/BLoC
class LoginBloc extends Bloc<LoginEvent, LoginState> {
final LoginUseCase loginUseCase;
LoginBloc({required this.loginUseCase})
: super(const LoginState.initial()) {
on<LoginButtonPressed>(_onLoginButtonPressed);
}
Future<void> _onLoginButtonPressed(
LoginButtonPressed event,
Emitter<LoginState> emit,
) async {
emit(const LoginState.loading());
await loginUseCase.call(
LoginInput(email: event.email, password: event.password),
_LoginPresenter(emit),
);
}
}
// Presenter реализует Output
class _LoginPresenter extends LoginOutput {
final Emitter<LoginState> emit;
_LoginPresenter(this.emit);
@override
void onSuccess(User user) {
emit(LoginState.success(user));
}
@override
void onEmailError(String message) {
emit(LoginState.emailError(message));
}
@override
void onPasswordError(String message) {
emit(LoginState.passwordError(message));
}
@override
void onServerError(String message) {
emit(LoginState.serverError(message));
}
}
Преимущества Interactor
- Независимость — бизнес-логика не зависит от UI или БД
- Тестируемость — легко написать unit-тесты
- Переиспользование — один Interactor для разных UI (BLoC, Riverpod, GetX)
- Чистота — разделение ответственности
- Масштабируемость — легко добавлять новые сценарии
Interactor — это сердце приложения, где живёт вся полезная бизнес-логика.