Какова роль паттерна репозиторий
Что проверяют
Понимаете ли вы, какую проблему решает репозиторий, а не только умеете нарисовать протокол с методами fetch и save. Следом обычно спрашивают, чем репозиторий отличается от сетевого сервиса и как вы его тестируете.
Как отвечать
Репозиторий это единая точка доступа к данным одной сущности, которая прячет, откуда они берутся. Экран или use case просит пользователя по id, а откуда он придёт, из кэша, из Core Data или SwiftData, из сети через URLSession, решает репозиторий.
Что стоит назвать:
- протокол:
protocol UserRepository { func user(id: User.ID) async throws -> User }. Реализацию подставляют через внедрение зависимостей, в тестах вместо неё фейк в памяти; - координация источников: политика кэша (сначала кэш, потом сеть, или показать устаревшее и обновить в фоне), слияние локальных и серверных данных, офлайн-режим;
- маппинг: сеть отдаёт DTO на
Codable, база хранит свои объекты, наружу выходят доменные модели. НиNSManagedObject, ни сетевые структуры за пределы слоя не утекают; - ошибки: сетевые ошибки и ошибки базы переводятся в понятные домену, например
notFoundилиoffline; - потокобезопасность: in-memory кэш удобно держать в
actor, изменения отдавать черезAsyncStreamили паблишер Combine.
Отличие от сервиса: APIClient знает про эндпоинты и HTTP, репозиторий знает про сущность и комбинирует источники. В VIPER репозиторий вызывает Interactor, в MVVM ViewModel, чаще через use case.
Где спотыкаются
Делают репозиторий тонкой обёрткой над одним сетевым запросом. Он добавляет файл и протокол, но ничего не прячет, и при одном источнике данных хватило бы сервиса.
Пропускают наружу модели хранения. Если ViewModel получает NSManagedObject, переезд с Core Data на SwiftData или добавление кэша потребует переписывать экраны, а ради этого паттерн и вводили.
Складывают в репозиторий бизнес-правила: расчёт скидки, валидацию, решения о навигации. Репозиторий отвечает на вопрос «где данные», а не «что с ними делать».