Подтвердить что ты не робот

Требуется ли проверка в CQRS раздельно один раз в пользовательском интерфейсе и один раз в бизнес-домене?

Недавно я прочитал статью 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 выполнить без ошибок.

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

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

4b9b3361

Ответ 1

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

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

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

[& hellip;] Даже если команда может быть действительной, все равно могут быть причины отклонить ее.

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

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

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

Ответ 2

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

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

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