我是CQRS的新手,在我的设计中需要关于以下情况的建议。命令更新聚合A的状态;因此需要用交叉聚合计算方法的结果更新读取模型;该方法属于另一个聚合B,它包含对聚合A的引用;该方法是聚合B和引用聚合A的状态的函数。
我的考虑(可以跳过):
我刚刚想到了以下解决方案:在域内,创建域事件‘聚合A更新’的处理程序。它将获取聚合B,调用其上的计算方法,然后用新的计算结果引发一个“聚合B函数结果更改”事件。然后,读取模型能够获取该事件的结果并更新自身。这样可以吗?
注意,以防万一我没有使用事件源。
如果对这种情况有任何想法,我将不胜感激。谢谢!
更新:使情况更加具体
我的聚合是工人的Workers (聚合B)和Groups (聚合B)。工人和团体是多对多的关系。假设一个组和一个工作人员都有一些Value属性。工人的calculateValue()是工人的值加上工人参与的所有组的值的函数。上面描述的命令正在修改某些组的Value。因此,所有参加组的工人都会返回不同的calculateValue()结果。
我想从阅读模型中得到什么?我需要一个包含计算值的员工列表(该列表已经说明了员工的所有组中的值)。我甚至不需要小组在阅读边。如果我用“在阅读方面做计算”的方式,我需要小组以及那里的关系的整体结构。恐怕这会是一个不合理的并发症。
发布于 2017-09-13 12:36:07
命令处理程序更新聚合A的状态在技术上可以从存储库中获取聚合B,调用它并将结果放到域事件中;但是,我认为除了一个被修改的聚合之外,获取聚合不是命令处理程序的任务,甚至是为了读取目的;而且也不是命令处理程序的任务是只执行与事件一起发送的计算而不是修改域状态。
这是不好的,因为事件应该代表与单个聚合有关的事实。
我知道命令所需的任何状态都必须与命令一起传递,该状态位于被修改的聚合的外部。这样,应用程序服务在发送命令之前,可以从read模型中获取聚合B的状态,并将其放入命令中。为此,我必须将函数从聚合B移到某个服务,并传递A和B的状态,这将使聚合B更加贫血。加上上面提到的在命令处理程序中执行计算的问题。
不应在事件中发送聚合状态。事实上,您不应该以任何其他方式查询聚合或使用它,而不是内部和私有状态,而是通过聚合本身。在CQRS中,聚合不被查询。这是读书人的目的。
我读过有人建议,任何只有读模型感兴趣的计算都属于读模型本身。因此,read模型的my事件处理程序将拥有执行计算所需的所有状态和行为。然而,这意味着我必须在查询端复制许多域模型概念;如果没有一个完整的读取模型,就太复杂了。
这就是该走的路。但是,你到底复制了什么呢?聚合是否使用该计算的结果来接受或拒绝其任何命令?
(如果是),则应该在聚合内部完成,在命令执行时完成,并可能完成沿事件发送的最终结果,但前提是只能使用来自命令和/或内部聚合状态的数据来完成计算,而不是通过交叉聚集状态。如果聚合需要来自其他集合的数据,那么这表明您的集合边界可能是错误的。
,如果不是,那么计算不应该停留在聚合中,而应该只停留在读取模型中。
在CQRS中,通过从Read模型中分离写,您也可以将计算拆分为写和读,但是在某些情况下,两个模型共享计算。在这些情况下,您可以提取类中的计算,并在两个模型中使用该类。
https://stackoverflow.com/questions/46197011
复制相似问题