Должна ли валидация в CQRS происходить отдельно, один раз в пользовательском интерфейсе и один раз в бизнес-сфере? - PullRequest
30 голосов
/ 06 марта 2011

Я недавно прочитал статью CQRS à la Greg Young и все еще пытаюсь разобраться с CQRS.

Я не уверен в том, где должна происходить проверка ввода и возможно ли это должно происходить в двух разных местах (что нарушает правило «Не повторять себя» и, возможно, также разделение проблем).

Учитывая следующую архитектуру приложения:

#      +--------------------+           ||
#      |    event store     |           ||
#      +--------------------+           ||
#           ^          |                ||
#           |  events  |                ||
#           |          v                  
#      +--------------------+         events         +--------------------+
#      |      domain/       | ---------------------> |   (denormalized)   |
#      |  business objects  |                        |  query repository  |
#      +--------------------+           ||           +--------------------+
#         ^   ^   ^   ^   ^             ||                      |
#         |   |   |   |   |             ||                      |
#      +--------------------+           ||                      |
#      |    command bus     |           ||                      |
#      +--------------------+           ||                      |
#                ^                                              |
#                |             +------------------+             |
#                +------------ |  user interface  | <-----------+
#                  commands    +------------------+        UI form data  
  • Домен скрыт от пользовательского интерфейса за командной шиной.То есть пользовательский интерфейс может только отправлять команды в домен, но никогда не попадает в доменные объекты напрямую.

  • Проверка должна не происходить, когда агрегированный корень реагируетна событие, но раньше.

  • Команды превращаются в события в домене (по совокупным корням).Это единственное место, где может произойти проверка: если команда не может быть выполнена, она не превращается в соответствующее событие;вместо этого (например) выдается исключение, которое всплывает через командную шину обратно в пользовательский интерфейс, где оно перехватывается.

Проблема:

Если команда не может быть выполнена, я хотел бы отключить соответствующую кнопку или пункт меню в пользовательском интерфейсе.Но как мне узнать, может ли команда выполняться перед отправкой?Сторона запросов здесь мне не поможет, так как она не содержит никакой бизнес-логики;и все, что я могу сделать на командной стороне, это отправить команды.

Возможные решения:

  • Для любой команды DoX введите соответствующую фиктивную команду CanDoX , которая на самом деле ничего не делает, но позволяет домену дать обратную связь, может ли команда X выполнить без ошибок.

  • Дублируйте некоторую логику проверки (которая действительно принадлежит домену) в пользовательском интерфейсе.

Очевидно, что второе решение не подходит (из-за отсутствия разделения интересов ).Но первый действительно лучше?

Ответы [ 2 ]

9 голосов
/ 07 марта 2011

Я думаю, что мой вопрос был только что решен другой статьей, Уточненный CQRS Уди Даханом.Раздел «Команды и проверка» начинается следующим образом:

Команды и проверка

Обдумывая, что может сделатьошибка команды, одна тема, которая появляется, является проверкой.Валидация отличается от бизнес-правил тем, что в ней указывается независимый от контекста факт о команде.Либо команда действительна, либо нет.С другой стороны, бизнес-правила зависят от контекста.

[…] Несмотря на то, что команда может быть действительной, все же могут быть причины для ее отклонения.

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

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

Следовательно, команды CanDoX не требуются, и не требуется утечка логики проверки доменав пользовательский интерфейс.Однако пользовательский интерфейс будет иметь некоторую логику для проверки команд.

2 голосов
/ 10 марта 2011

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

Итак, клиентская сторона должна проверять только все ли обязательные поля заполнены и имеют ли они правильную форму (поле адреса электронной почты должно содержать действительный адрес электронной почты, например, формы (. +) @ (. +). (. +) или тому подобное).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...