another_dream
@another_dream
Backend-разработчик, Laravel/ZF2/Yii2

Как произвести валидацию модели до сохранения при использовании паттерна Repository?

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

Задача: проверить валидность данных, поступивших от клиента, к примеру, это комментарий.

Как бы я сделал без репозитория, примитивно:
$model = new Comment(); // Comment наследуется от ActiveRecord
$model->load(Yii::$app->request->post());
$model->validate(); // true/false


При использовании репозитория подобный вариант имеет место быть? Как лучше решить данную задачу?

Предположение

Можно вынести валидацию данных из AR модели в отдельную модель, наподобие FormRequest из Laravel, валидировать и уже после этого отдавать репозиторию на сохранение.
  • Вопрос задан
  • 488 просмотров
Решения вопроса 1
Deroy
@Deroy
Senior Developer, Software Architect
при использовании паттерна репозиторий вам стоит перестать думать о модели которая путешествует через систему, как о месте где должна случаться валидация входных данных. Такой подход получил распространение благодаря RAD-framework'ам (Yii и ему подобные) - упрощенка цель которой - быстрая скорость разработки.

Если смотреть на архитектуру с точки зрения "чистоты", то:

Модель которая путешествует через всю систему должна содержать в себе только доменную логику, или не содержать ее вовсе (т.е. по факту являться Value-object'ом).

Валидация входных данных описывается отдельной моделью - моделью реквеста - и содержит в себе логику валидации/маппинга/и пр.

т.е. более менее стандартный подход со стороны расширяемости, надежности, тестируемости и гибкости приложения к последующим изменениям - это иметь валидацию/парсинг входных данных отдельно для каждого случая (например отдельно для вебформ и отдельно для JSON/XML/etc API, конечно фрагменты могут быть переиспользованы, наследованы или примешаны и т.д.), модели - отдельно, работу со стораджом отдельно.

Последнее вы уже сделали = репозиторий как раз оно.

Так что ваше предположение - верно.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
mitaichik
@mitaichik
Репозиторий (хранилище) должен содержать логику сохранения/поиска/восстановления объектов. Валидация - это как бы не его задача. В энтерпрайз фреймворках для этого создаются отдельные сущности.

Что касается Yii - то в нем ActiveRecord несет несколько обязанностий: это и сущность с бизнес-логикой, и валидатор, и репозиторий, и жизненный цикл и т.п. Вы вынесли логику хранения в репозиторий, хорошо. Теперь вам нужно выносить логику валидации куда-то.

Но, с другой стороны, почему бы не пользоваться функционалом фреймворка и не оставить обязанность валидации в модели? Какие-то суперсложные валидаторы можно вынести в отдельные классы валидаторов.

Я это все к тому, что если вы все это хотите выносить, и идти против архитектуры фреймворка (что не так-то просто), то зачем использовать Yii? Может лучше сразу взять фреймворк который более подходит к вашей архитектуре?
Ответ написан
index0h
@index0h
PHP, Golang. https://github.com/index0h
В случае репозитория у вас есть энтити, содержащее данные, которые будет обрабатывать репозиторий. Обычно валидация выполняется в сеттерах энтити, или конструкторе. Можно ее выполнять и в репозитории, в этом случае можно обрабатывать энтити по интерфейсу.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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