Задать вопрос

Репозиторий и ActiveRecord, хорошая ли идея возвращать модели?

Несколько месяцев разрабатывал на laravel5 и понял, что весьма накосячил с репозиториями, а точнее КПД получил примерно 0. Сейчас пытаюсь понять, как все это дело исправить и узнать мнения разных спецов.

Когда я лазил по интернету, то находил различные приложения, где примерно так-же косячат как и я. Вот пример такого приложения:
https://github.com/Bottelet/Flarepoint-crm/

Репозиторий:
https://github.com/Bottelet/Flarepoint-crm/blob/de...

Собственно какие тут проблемы:
- логика в репозитории
- дубль запроса в методе update (мы передаем $id, из модели, чтобы получить модель). У себя в приложении я накосячил еще более жестче, так как передавал еще и модель, чтобы избавиться от этого запроса.
- нарушение единой ответственности (bcrypt)
- возврат модели в качестве результата из репозитория.

Тоесть, если использовать репозитории, как действительно репозитрои и подменить скажем запрос модели на запрос с помощью квери билдера и в один прекрасный день из репозитория вернется не модель, а коллекция, то это не гарантирует никакой стабильной работы приложения.

От сюда вопрос, зачем тут репозитории, если это абстрактное хранилище над моделями, а не абстрактное хранилище в целом?

Ну и основной вопрос, в правильном ли я направлении формирую мысли, и как подобный подход с репозиториями можно реализовать правильно ?
  • Вопрос задан
  • 3513 просмотров
Подписаться 19 Оценить 4 комментария
Решения вопроса 4
AmdY
@AmdY
PHP и прочие вебштучки
Это типичный пример, когда люди не сами доходят до паттернов, а начитываются умных книг и суют свои репозитории и ддд без понятия зачем это нужно.
Сколько уже статей видел об использовании репозиториев в laravel, все прдлагают куегкт Model::all() и т.д. Плевать, что возвращают всё тот же Eloquent, который пытаются убрать.

В проектах на symfony даже при наличии doctrine творится такой же ад. То. что люди не умеют делать нормальные репозитории указывает на то, что оно им и не надо было такой абстракции. Для 99% проектов вообще не стоит тащить абстракции вроде репозиториев.
Ответ написан
index0h
@index0h
PHP, Golang. https://github.com/index0h
Ну и основной вопрос, в правильном ли я направлении формирую мысли, и как подобный подход с репозиториями можно реализовать правильно ?

Если хотите по правильному - не используйте ларавелевскую ORM, "воевать" с фреймворком - это дело не благодарное.
Паттерн Repository как правило предполагает еще наличие Entity. Entity - это объект, умеющих хранить в себе данные и проверять их при установке. Репозиторий работает только с Entity и только с БД. Никаких bcrypt, работы с файлами, никаких уведомлений...
Не стоит использовать публичные свойства. В противном случае вы не сможете гарантировать корректность данных в вашем Entity, как следствие всюду их придется проверять. Используйте тайпхинтинг.
Так же рекомендую почитать: Попросили проверить код, на что смотреть нужно?
Ответ написан
Комментировать
dmitriylanets
@dmitriylanets
веб-разработчик
1. репозитрии должны инкапсулировать логику работы с хранилищем все остальное выносите в сервисы пример
2. Возвращаться должны не модели а Entity, модель в laravel это activerecord. Возможно по этому репозитории в laravel избыточны.
3. вот хороший видос
Ответ написан
Тоже столкнулся с таким. Есть мнение, что модели возвращают потому, что в них уже можно прописать все необходимое для вывода данных, равно как и спрятать лишние поля, а также преобразовать/добавить недостающие атрибуты. Но наличие метода save() за пределами репозитория смущает. На данный момент пришел к тому, что репозиторий у меня преобразует модели в сущности (самопальными трансформерами наподобие fractal.thephpleague.com) перед тем, как отдать их, но с логикой сохранения внутри репозитория пока не пришел к конечному варианту - часто в проекте требуется не просто сохранить строку в бд в одну таблицу, а сделать гораздо более сложные вещи и вся эта логика завязана именно на процесс сохранения, поэтому не вижу способа вынести эту логику куда-то из репозитория. Но такие вещи, как return session()->flash() в примере по вашей ссылке, считаю лучше на уровне выше генерировать в зависимости от отданных репозиторием данных, они тут вообще никаким местом.

Вообще сам пока ищу наиболее удобный вариант построения приложений (засматриваюсь на гексагональную архитектуру), но применить что-то глобальное на проекте, которым занимаюсь уже год и который разрабатывался с 2014 года просто не могу. Поэтому рассматривайте мои измышления лишь как рассуждения человека, столкнувшегося с этой же проблемой и находящемся на том же пути.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы