@alexber220

Как правильно валидировать атрибуты сущности?

Столкнулся с противоречием при реализации сущностей в рамках DDD. С одной стороны мы должны следить за тем чтобы не было возможности получить сущность в невалидном состоянии, а с другой показать в пользовательском интерфейсе какие значения неправильные и почему. Как быть если ошибка в нескольких атрибутах сущности? Дублировать валидацию на клиенте и сервере не хочется. В примерах которые находил кидается исключение сразу при попытке установить неправильное значение атрибута. Что если передавать в конструктор объект в который будут складываться ошибки и в случае появления ошибок в конструкторе объекта они добавляются туда и в самом конце выдаётся исключение? Может я придумываю велосипед и есть уже устоявшееся решение?
  • Вопрос задан
  • 619 просмотров
Пригласить эксперта
Ответы на вопрос 2
skobkin
@skobkin
Гентушник, разработчик на PHP и Symfony.
А почему вы не можете валидировать данные до передачи в сущность?
Если посмотрите на тот же фреймворк Symfony - компонент валидации вообще не привязан к другим частям системы.
Ответ написан
@ddd329
Привет!

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


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

Как быть если ошибка в нескольких атрибутах сущности?


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

Дублировать валидацию на клиенте и сервере не хочется


Дублировать валидацию можно, если она общеизвестная, например ФИО или email-адрес, зачем перепадать эти значения на сервер, когда в браузере можно выполнить их полноценную валидацию, что повысит время отклика UI. А если логика специфичная, что чаще и бывает, то бизнес-правила должны "лежать" на уровне домена, и не выше.

В общем, мне известно два варианта создания сущностей: используя только публичный конструктор, или используя фабрику(factory). Если я вас правильно понял, то у вас имеется форма с полями для заполнения их значениями, которые являются атрибутами какой-то сущности?
Здесь могут быть два сценария, первый: когда сущность, а точнее АГРЕГАТ, извлекается из репозитория с целью редактирования, то здесь все так, как вы описали выше: неверное значение атрибута - выбрасываем исключение.
И второй сценарий - создание сущности. Нигде нельзя получить доступ к невалидной сущности, созданной с помощью оператора new DomainObject() кроме как фабрики. Поэтому создавайте фабрику, которая позволяет строить вашу сущность, а точнее АГРЕГАТ, по шагам. Для этого примените паттерн проектирования СТРОИТЕЛЬ (Builder). В конце вызовите метод Build(), который и вернет вам валидный АГРЕГАТ.
Что качается промежуточных результатов "строительства", то для их получения используйте паттерн проектирования СНИМОК (Memento), например вот так: var snapshot = domainObjectFactory.GetSnapshot();, где snapshot обычная DTO-ошка, которая содержит значения атрибутов сущностей и списки ошибок, валидность и т.д. Ну а дальше смотрите сами как быть, если вы на клиента передаете ViewModel-s, то используя snapshot создавайте модели представления и дальше их на UI пользователя.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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