我是 CQRS 的新手,在我的设计中需要关于以下情况的建议。一条命令更新聚合 A 的状态;因此需要使用交叉聚合计算方法的结果更新读取模型;此方法属于另一个聚合 B,该聚合 B 持有对聚合 A 的引用;该方法是聚合 B 和引用聚合 A 的状态的函数。调用此函数的正确位置在哪里?
我的考虑(可以跳过):
- 命令处理程序更新聚合 A 的状态,技术上可以从存储库中获取聚合 B,对其调用计算并将结果放入域事件中;但是我认为获取聚合而不是被修改的聚合不是命令处理程序的工作,即使是出于阅读目的;此外,执行计算以发送事件而不是修改域的状态也不是命令处理程序的工作。
- 域事件('聚合 A 已更新')仅包含聚合A的更新状态,聚合B的状态信息不足。读取模型的事件处理程序无法访问域模型,因此它既不能获取聚合B 也不在聚合 B 上调用所需的函数来更新读取模型。
- 我知道命令所需的任何状态都在被修改的聚合外部,必须与命令一起传递。这样,应用服务在发送命令之前可以获取聚合 B 的状态(从读取模型中),并将其放入命令中。为此,我必须将函数从聚合 B 移动到某个服务,并在那里传递 A 和 B 的状态。这会使聚合 B 更加贫乏。加上上面提到的在命令处理程序中进行计算的问题。
- 我读过有人建议只有读取模型感兴趣的任何计算都属于读取模型本身。因此,我的事件的读取模型处理程序将拥有执行计算所需的所有状态和行为。但是,这意味着我必须在查询端复制许多域模型概念;拥有完整的读取模型太复杂了。
我刚刚想到了以下解决方案:在域中,创建域事件“ Aggregate A updated ”的处理程序。它将获取聚合 B,对其调用计算方法,然后引发一个“聚合 B 函数结果已更改”事件,其中包含新的计算结果。然后读取模型能够从该事件中获取结果并更新自身。这样可以吗?
请注意,以防万一我没有使用事件溯源。
对这种情况的任何想法将不胜感激。谢谢!
更新: 使情况更加具体
我的聚合是Worker
s(聚合 B)和Group
工人的 s(聚合 B)。Workers 和 Groups 是多对多的关系。想象一下 Group 和 Worker 都有一些Value
财产。Worker'scalculateValue()
是 Worker 的 Value 加上 Worker 参与的所有 Group 的 Value 的函数。上面描述的 Command 是Value
针对某个 Group 进行修改的。结果,参与该组的所有工人将返回不同的结果calculateValue()
。
我想从读取模型中得到什么?我想要一个具有计算值的工人列表(已经考虑了工人所有组的值)。我什至不需要 Group 在读取端。如果我采用“在读取端进行计算”的方式,我需要组以及那里的整个关系结构。恐怕这将是一个不合理的并发症。