Я новичок в CQRS и мне нужен совет по следующей ситуации в моем дизайне. Команда обновляет состояние агрегата A; следовательно, модель чтения должна быть обновлена с использованием метода расчета перекрестных агрегатов; этот метод принадлежит другому агрегату B, который содержит ссылку на агрегат A; метод является функцией состояний агрегата B и указанного агрегата A. Где правильное место для вызова этой функции?
Мои соображения (можно пропустить):
- Обработчик команд, обновляющий состояние агрегата A, может технически извлечь агрегат B из репозитория, вызвать вычисление для него и поместить результат в событие домена; однако я считаю, что извлечение агрегатов, кроме изменяемого, не является задачей обработчика команд, даже для чтения; Кроме того, это не задача обработчика команд выполнять вычисления только для отправки с событиями, а не для изменения состояния домена.
- Событие домена ('Aggregate A updated'), вызванное агрегатом A, содержит только обновленное состояние агрегата A, недостаточно информации о состоянии агрегата B. Обработчик событий модели чтения не имеет доступа к модели предметной области , поэтому он не может ни получить агрегат B, ни вызвать нужную функцию на агрегате B для обновления модели чтения.
- Я знаю, что любое состояние, необходимое команде, которое является внешним по отношению к изменяемому агрегату, должно передаваться вместе с командой. Таким образом, служба приложения перед отправкой команды может получить состояние агрегата B (из модели чтения) и поместить его в команду. Для этого мне пришлось бы переместить функцию из агрегата B в какую-либо службу и передать туда состояния как A, так и B. Это сделало бы агрегат B более анемичным. Плюс вышеупомянутая проблема с выполнением вычислений в обработчике команд.
- Я читал людей, предполагающих, что любые вычисления, которые интересуют только модели чтения, принадлежат самой модели чтения. Таким образом, обработчик модели чтения моего события будет просто иметь в своем распоряжении все необходимое состояние и поведение для выполнения вычислений. Однако это означало бы, что мне придется дублировать большую часть концепций модели предметной области на стороне запроса; Было бы слишком сложно иметь полноценную модель чтения.
Я только что подумал о следующем решении: создать в домене обработчик события домена «Aggregate A updated». Он получит агрегат B, вызовет для него метод вычисления, а затем вызовет событие «Результат функции агрегирования B изменен» с новым результатом вычисления в нем. Затем модель чтения сможет получить результат этого события и обновить себя. Это было бы нормально?
На всякий случай обратите внимание, что я не использую Event Sourcing.
Будем очень признательны за любые мысли по поводу этой ситуации. Спасибо!
ОБНОВЛЕНИЕ: конкретизация ситуации
Мои агрегаты - это Worker
s (агрегат B) и Group
s рабочих (агрегат B). Рабочие и группы - это отношения «многие ко многим». Представьте, что и у группы, и у рабочего есть какое-то свойство Value
. Рабочий calculateValue()
является функцией Ценности рабочего плюс Ценности всех групп, в которых он участвует. Команда, описанная выше, изменяет Value
для некоторой группы. В результате все рабочие, участвующие в группе, вернут разные результаты calculateValue()
.
Что я хочу от прочитанной модели? Мне нужен список рабочих с рассчитанными значениями (которые уже учитывают значения из всех групп рабочих). Мне даже не нужна группа на стороне чтения. Если я пойду методом «выполнить расчет на стороне чтения», мне понадобятся группы, а также вся структура отношений в них. Боюсь, это будет неоправданное осложнение.
getAnotherAggregateID()
метод? - person Pavel S.   schedule 13.09.2017