acwa_book_ru
acwa_book_ru copied to clipboard
Почему считается, что модели eloquent имеют минимум две ответсвенности?
В главе "Внедрение зависимостей" встретил следующую фразу:
Классы Eloquent моделей содержат как минимум две ответственности: хранение состояния сущности и выборку/сохранение/удаление сущностей из базы
В связи с этим, у меня возникли следующие вопросы:
- Взаимодействие с базой это не часть ответственности по хранению данных? Я думаю хранение данных должно предусматривать взаимодействие с каким-либо персистентным хранилищем, иначе это не хранение.
- Почему тогда, например, обязанности класса Request не определить как:
- хранение данных HTTP запроса
- парсинг HTTP запроса
Я считаю, что иметь состояние для класса в ООП это не обязанность. Все объекты в ООП (даже т.н. stateless сервисы) имеют состояние, взять хотя бы внутренний идентификатор, зависимости, конфигурацию. Почему наличие атрибутов с данными в моделях Eloquent считаются отдельной ответственностью?
Привет, Антон. В главе про доменный слой я разовью мысль, что персистить данные - это просто необходимое зло) и для некоторых приложений логика в классах-моделях намного сложнее логики хранения их в базе данных. Это две разные логики, но элоквент соединяет их в одну и получаются фактически строчки в базе данных, которые с собой какую-то логику несут. Эти две ответственности и назвал. Но, вероятно, надо исправить немного это предложение как-нибудь.
Классы Eloquent моделей содержат как минимум две ответственности: хранение состояния сущности и выборку/сохранение/удаление сущностей из базы
Вопрос в том, что нарушается SRP?
Я не вижу тут беспокойств. Причина внесения изменений в Eloquent одна - может поменяться что-то в базе данных. Со связностью (cohesion) всё впорядке, все методы сконцентрированы одной цели - работа с данными из базы данных. А вот если бизнес логика начинает появляться в Eloquent - вот тогда плохо...
Евгений, я говорил ещё и о выборках из базы и методах сохранения/удаления. Все эти Soft delete, скоупы люди часто суют в классы моделей. И если скоупы ещё можно как-то отдельно держать (хотя это и не модно), то глобальные скоупы, такие как софт делит - не получится. Это немного другая логика, чем представление строки из бд.
А вот если бизнес логика начинает появляться в Eloquent - вот тогда плохо...
@githubjeka Много раз видел как используют подход "Тонкие Контроллеры -> Толстые Модели".
Скоупы получения данных где уже вшита бизнес логика, с (например) той же фильтрацией по типу пользовательского аккаунта (простой/премиум).
Скоупы которые являются не продолжением Eloquent\Builder
а которые вызывают get()
и возвращают результат.
Так что в реальных проектах, тезис
Причина внесения изменений в Eloquent одна - может поменяться что-то в базе данных. получается не всегда правдивым.
И причиной изменения моделей становится банальное изменение бизнес логики.
Приведу пример с скоупом.
$users = User::onlyActive()->get();
И тут уже зарыта собака, ведь сегодня только активные пользователи это те у кого email_verified_at != NULL
а завтра уже и у кого phone != null
и profile()->exists()
и т.д.
Удобно же правда, вроде KISS а вроде уже смешивание слоев, и в будущем, лично я, побоюсь добавить или изменить этот скоуп, ведь потому что PHPStorm и магия Laravel не дает мне интуитивно найти места где используется этот метод. Да через глобальный поиск можно, но скоупы же не всегда вызываются статично, однажды это из инстанца, а иногда вообще из Builder. Пример:
$user = new App\Models\User;
return $user->onlyActivated()->get();
# Файл App\Models\User.php
//...
public function scopeOnlyActive($builder) {
return $builder->whereNotNull('email_verified_at');
}
public function scopeOnlyActivated($builder){
return $builder->onlyActive();
}
пы. сы. В определённых кругах, за то что в Laravel используется Active Record и Model - архитекторы настаивают на замене его на Doctrine :) пы. сы. сы С последним примером скупов я сомневался, и попробовав я, честно говоря, удивлен что оно работает.
В вашем примере "собака зарыта" не в Active Record , а в том, что нет единого АPI получения активных пользователей.
... что нет единого АPI получения активных пользователей.
Вы правы, собака зарыта в разработчиках которые так пишут как у меня в примере. В тех кто вставляет бизнес валидацию и логику в модель данных.
С одной стороны они то правы, любой обучающий ресурс им так диктует. Мол: тут мы "отфильтруем" данные с помощью "скоуп функций". А тут пользователь сам себе вышлет новый эмелй.
Я просто хотел своим сообщением вам показать что утверждение
Причина внесения изменений в Eloquent одна - может поменяться что-то в базе данных. получается не всегда правдивым. Не так верно как кажется.
И я согласен с вами, я бы тоже хотел изменять модель в соотвествии только с изменениями в схеме.