Что такое паттерн use case
Что проверяют
Различаете ли вы два разных предмета с одним названием: use case как описание сценария в требованиях и use case как слой кода в чистой архитектуре. На собеседовании по iOS почти всегда спрашивают второе: объект, который выполняет один сценарий приложения.
Как отвечать
Use case (он же интерактор) это объект с одной операцией, выражающей намерение пользователя: загрузить ленту, оформить заказ, выйти из аккаунта. Внутри он собирает работу репозиториев и сервисов и возвращает результат в терминах предметной области, ничего не зная ни об экране, ни о транспорте.
protocol LoadFeedUseCase {
func execute(page: Int) async throws -> [FeedItem]
}
final class LoadFeed: LoadFeedUseCase {
private let repository: FeedRepository
private let profile: ProfileStorage
init(repository: FeedRepository, profile: ProfileStorage) {
self.repository = repository
self.profile = profile
}
func execute(page: Int) async throws -> [FeedItem] {
let filters = profile.savedFilters
return try await repository.load(page: page, filters: filters)
}
}Зачем это нужно: модель представления перестаёт распухать и склеивать несколько источников, сценарий переиспользуется на разных экранах, а тест пишется на чистую логику без интерфейса, потому что зависимости объявлены протоколами и подменяются заглушками.
Где спотыкаются
Делают из сценария пустой переходник в репозиторий. Слой с одним методом, который дословно вызывает другой метод, добавляет только файлы; выделять сценарий стоит там, где есть собственная логика, координация нескольких источников или правила доступа.
Отвечают про акторов, предусловия и постусловия, когда спрашивают про архитектуру приложения. Это словарь требований, а не кода; про него уместно сказать одной фразой и сразу перейти к слою со сценариями.
Тащат внутрь типы интерфейса. Как только в сценарии появляется представление, контроллер или модель ответа сети, слой теряет смысл: тестировать его становится так же тяжело, как экран, а переиспользовать невозможно.