Ответ
В Clean Architecture (и таких её вариантах, как VIPER) Use Case и Interactor — это тесно связанные, но концептуально разные компоненты.
Определения:
- Use Case (Сценарий использования) — это бизнес-правило или требование. Он описывает ЧТО должна сделать система (например, "получить список новостей", "создать заказ"). Use Case — это абстракция, часто представленная в виде протокола/интерфейса.
- Interactor (Интерактор) — это конкретный исполнитель бизнес-логики. Он реализует один или несколько Use Cases, координируя работу сущностей (Entities) и внешних зависимостей (например, репозиториев). Он описывает КАК выполнить задачу.
Аналогия:
Use Case — это чертёж или техническое задание ("построить дом").
Interactor — это прораб, который организует процесс, нанимает строителей (репозитории) и следит за выполнением работ по этому чертежу.
Пример кода:
1. Use Case (протокол, определяющий контракт):
// Описывает ЧТО нужно сделать. Не зависит от фреймворков (UIKit, Core Data).
protocol FetchUserProfileUseCase {
func execute(userId: String) async throws -> UserProfile
}
2. Interactor (конкретная реализация Use Case):
// Реализует КАК это сделать. Содержит бизнес-логику.
class FetchUserProfileInteractor: FetchUserProfileUseCase {
// Зависимости инжектируются (репозиторий, сервис)
private let userRepository: UserRepositoryProtocol
private let analyticsService: AnalyticsServiceProtocol
init(userRepository: UserRepositoryProtocol, analyticsService: AnalyticsServiceProtocol) {
self.userRepository = userRepository
self.analyticsService = analyticsService
}
func execute(userId: String) async throws -> UserProfile {
// 1. Координация бизнес-логики
let user = try await userRepository.fetchUser(by: userId)
// 2. Дополнительные правила (например, кэширование, логирование)
analyticsService.trackEvent("user_profile_fetched", userId: userId)
// 3. Преобразование данных для возврата
return UserProfile(from: user)
}
}
Ключевое отличие:
- Use Case — это декларация намерения (интерфейс). Он принадлежит слою бизнес-правил.
- Interactor — это реализация этого намерения с конкретной логикой и зависимостями. Он служит мостом между бизнес-правилами (Use Case) и слоем данных (репозитории).
Такое разделение делает код тестируемым (Use Case можно замокать) и позволяет менять реализацию (Interactor), не меняя объявленный контракт.