Нарушает ли принцип единственной ответственности класс репозиторий, который читает, записывает и удаляет данные из базы
Что проверяют
Понимаете ли вы SRP как принцип про причины изменений, а не как правило «один метод на класс». Это вопрос с подвохом: правильный ответ «нет, не нарушает», и дальше интервьюер спросит, что должно оказаться в репозитории, чтобы нарушение появилось.
Как отвечать
Роберт Мартин формулирует SRP так: у модуля должна быть одна причина для изменения, то есть он отвечает перед одним актором. Чтение, запись и удаление сущности User меняются по одной причине: поменялось хранилище или схема данных. Это одна ответственность, хранение пользователей, и CRUD в одном репозитории её не нарушает.
В iOS это обычно выглядит так:
- протокол:
UserRepositoryс методамиfetch,save,delete, от него зависят Interactor или ViewModel; - реализации:
CoreDataUserRepository,SwiftDataUserRepositoryили обёртка над GRDB, а в тестах заглушка в памяти; - маппинг: превращение
NSManagedObjectв доменную модель остаётся внутри реализации и наружу не протекает.
Нарушение появляется, когда в репозиторий начинают складывать чужое: бизнес-правила вроде «удалить можно только неактивного», форматирование для экрана, отправку аналитики, синхронизацию с сервером вперемешку с кэшем. Каждое из этого меняется по своей причине и по запросу разных людей.
Если некоторым клиентам нужно только чтение, разделение на UserReading и UserWriting уместно, но это принцип разделения интерфейсов (ISP), а не SRP. В Swift их удобно собрать обратно композицией: typealias UserRepository = UserReading & UserWriting, и одна реализация закроет оба протокола.
Где спотыкаются
Отвечают «да, нарушает» и предлагают ReadRepository, WriteRepository, DeleteRepository. Это дробление без выгоды: все три будут меняться одновременно при смене хранилища.
Путают SRP с ISP и не могут объяснить, чем разделение по клиентам отличается от разделения по причинам изменений.
Делают один репозиторий на все сущности приложения. Вот он как раз нарушает SRP: правка модели заказов трогает файл, через который работают пользователи и настройки.