Недавно понял, почему у меня нет необходимости в репозиториях.

У меня просто нет доменного слоя, за счёт того что я ухитрился настолько упростить код что и слои оказались лишними.

Ну а без доменного слоя и репозитории это излишество.

Как упрощается код

Вот что помогает мне упростить код:

  1. Перепроектирование под изменённые требования
  2. Следование принципам чистой архитектуры, в том числе SOLID, и следование принципам чистого кода
  3. Использование шаблонов проектирования, таких как DTO и VO, посредники (“обёртки” в моей интерпретации)
  4. Разделение функциональности на модули “вертикальными срезами”
  5. Устранение техдолга не только в коде но и в БД
  6. Система “сущность-модель” которая позволяет не тащить детали общения с БД в код бизнес-логики

Каждый отдельный метод немного улучшает качество кода, а используя их все, качество и простота кода вырастает значительно.

Мой опыт с репозиториями

Как и большая часть опытных программистов, когда-то я впервые познакомился с репозиториями и был очень впечатлён мощностью этой концепции.

Надо же, можно отделить полностью хранилище данных от логики процессов и сделать код который будет независим от хранилища!

Это действительно круто. Но внедрив в один из своих проектов повсеместно репозитории, я убедился что они несут с собой очень много лишнего кода.

В большинстве случаев вам не требуется использовать одновременно разные типы хранилищ, а вследствие этого реализация репозитория будет в одном экземпляре.

Имея реализацию в одном экземпляре, встаёт вопрос, а зачем нам тогда вообще отделять этот код по общению с БД в репозиторий? Не лучше ли оставить его там где он был?

Минусы репозиториев

Основные минусы репозиториев:

  • Нужно писать больше кода
  • Код становится сложнее из-за увеличения количества абстракций
  • Тратится больше времени на создание и сопровождение кода

Плюсы репозиториев

Основные плюсы репозиториев:

  • При правильной реализации, код становится независимым от хранилища данных
  • Код становится чище так как детали взаимодействия с БД переезжают в репозиторий
  • DDD!

Отмечу, впрочем, что преимущество с очисткой кода от деталей взаимодействия с БД можно получить и без использования репозиториев.

Сервисный слой

Ещё до репозиториев, и до изобретения системы “сущность-модель” я практиковал метод создания сервисного слоя для БД.

Допустим, есть какой-то “заказ”. Тогда у меня будет OrderController, OrderService и Order.

Внутри OrderService будут находиться любые операции взаимодействия с БД: запросы на поиск, чтение, методы создания и измненения заказов.

При этом концентрируя в сервисе операции с БД, мы по возможности избавляем контроллер от этих деталей, а также сокращаем количество кода в модели.

Этот метод очень сильно упростил создание сложных проектов, но был не идеален.

Контроллер и вьюшки “знали” о полях модели, поэтому изменения в структуре БД всё же затрагивали их.

Стоп, а как же тестировать без репозиториев?

Очень просто, работайте на уровне “сущностей” если используете систему “сущность-модель”, обращайтесь к сервисам если у вас есть сервисный слой, или напрямую к моделям если его нет.

Но тогда мы будем обращаться к БД в тестах, а это плохо!

Почему же это плохо?

Сколько я ни спрашивал, убедительного ответа не получил.

Перечислю основные варианты ответов и мои возражения на эти ответы.

В книгах и статьях учат что это плохо — предпочитаю опираться на собственный опыт и логику, а не слепо доверять написанному. К тому же я слишком хорошо знаю примеры, когда авторы книг и статей “учат плохому” а потом приходится переучивать тех кто верит авторам на слово. Если автор вас убедил, приведите его аргументы, а не просто мнение.

Это медленно! — весомый аргумент, но при разумном подходе к тестированию, когда мы проверяем только необходимое, это уже не так важно. Если тесты выполняются менее минуты, я считаю их достаточно быстрыми.

А как тестировать без репозиториев?! — да вот так, использовать БД и всё.

У нас (в нашем проекте) так не получится — если структура вашего проекта не позволяет обойтись без репозиториев или моков в тестировании, вы можете преодолеть это повысив свои навыки тестирования или упростив проект. Конечно, можете остаться с репозиториями, ваше право. Встретив сложности в тестировании, я предпочитаю менять проект так, чтобы тестировать его было легко.

А что если БД выдала ошибку? И наш код не обеспечит надёжности в этом случае? Как мы это проверим? — при правильном проектировании кода такие проверки не требуются. Но если очень нужно, то решение найдётся и без репозитория. Если же применяем репозиторий с целью решения такой задачи, то держим в уме, что использование репозитория несёт свои издержки. Ради одного случая внедрять репозитории везде я бы не стал, слишком дорого обходится.

Зачем тогда нужны репозитории?

Если не для тестирования и не для упрощения кода, то зачем нужны репозитории?

Я бы стал использовать репозитории там, где изначально предполагается несколько вариантов хранилища.

Например, у нас есть модуль сессии и он в зависимости от настроек проекта хранит данные либо в БД, либо в файлах, либо в Redis.

В этом случае репозиторий уместен и полезен: он даст необходимое упрощение, так как изолирует основной код от каких-то знаний о хранилище.

Мы сможем добавить или удалить тип хранилища без изменения в основной логике, тем самым соблюдая “принцип открытости-закрытости”, OCP.

У тебя те же репозитории, ты просто их “сущностями” назвал!

Нет. Моя система “сущность-модель” отличается от репозиториев в первую очередь тем, что решает совершенно другую задачу.

Мои сущности полностью изолируют приложение от деталей реализации в БД.

Обычные “репозитории” — не книжные, а те которые мы видим повсеместно в проектах фанатов репозиториев — никак не изолируют код от БД, просто вводят ещё одну прослойку. Переименовал поле в БД или удалил таблицу — добро пожаловать, правь 100 мест в коде.

В моих сущностях изменения затронут только сами сущности и модели, причём модель является не более чем отражением таблицы. Прочий код приложения не поменяется.

Второе важное отличие: мои сущности содержат правила бизнес-логики, а репозитории призваны заниматься только операциями с БД на чтение и запись, сводя свои знания о бизнес-контексте к минимуму.

Они играют разные роли.

P.S.

Использовать репозитории или нет, решать вам.

Я лишь постарался подробно изложить свой взгляд на этот вопрос и поделиться тем что узнал.

Лучший способ узнать, нужны ли именно вам репозитории — просто попробовать.

Удачи!