Я недавно прочитал статью 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 выполнить без ошибок.
Дублируйте некоторую логику проверки (которая действительно принадлежит домену) в пользовательском интерфейсе.
Очевидно, что второе решение не подходит (из-за отсутствия разделения интересов ).Но первый действительно лучше?