Репозиторий и Eloquent

Октябрь, 2023

Запрещённые слова, Холивар

Одна из самых горячих тем в чатах, которая вспыхивает по КД. Сразу подчеркну, что этот текст мои (и не только) размышления на данную тему, поэтому никаких выводов о добре и зле здесь не будет.

# Быстрый ответ

Начнём с того, что если ты задаёшься вопросом «А нужны ли мне репозитории в Laravel?», то ответ будет простым: «Нет, не нужны».

По очень простой причине: если ты не знаешь зачем ты что-то делаешь, то этого делать не надо. А если знаешь зачем, то ты либо делаешь, либо нет и на этом собственно всё.

# Чтиво

Предлагаю ознакомится с более подробными материалами (комментарии тоже рекомендуются к прочтению):

Как не нужно использовать паттерн Repository
Пожалуйста, прекращайте говорить про шаблон Репозиторий с Eloquent
Полезные репозитории с Eloquent?
Почему здравый смысл важнее паттернов, а Active Record не так уж и плох

С материалами я согласен, поэтому здесь в точности повторяться смысла нет.

И немного о самом шаблоне проектирования:

Хранилище (Repository)
Паттерн репозиторий

# Суть холивара

Вся суть сводится к тому, что в Laravel репозитории - это бесполезный слой абстракции, поскольку Eloquent ORM - реализация ActiveRecord, уже является репозиторием. И те репозитории, что пишутся с Eloquent, в итоге не выполняют роль присущую паттерну.

# Зачем?

Чаще всего репозитории в Laravel используются разработчиками:

  • пришли с других фреймворков или языков, где привыкли иначе разделять бизнес-логику и работу с БД
  • пытаются устранить повторяющиеся запросы и сделать "сервис" отвечающий за выборку конкретных данных
  • решили, что использовать репозитории надо обязательно, по принципу «Здесь так принято»
  • для тестирования и моков

Всё это в той или иной мере может иметь смысл, но только потому, что смысл мы вкладываем сами. В реальности я вижу в проектах классы, которые в имени содержат постфикс Repository, но являются ли они репозиториями? Нет. Они являются обычными хелперами, в которые завернули QueryBuilder и которые возвращают модели. И модели дальше могут и будут использоваться в обход репозиториев. А методы эти либо бесполезные - getById(), либо узкоспециализированные getUserWithOrdersForCabinet(), которые используются один раз в одном месте приложения и являются обычными скоупами