我们开始在我们的系统中找到一些场景,其中针对聚合的命令的结果可以影响其他相关聚合。
为了演示这个问题,请考虑一个树结构,其中我们有拥有兄弟节点的节点。每个节点都有一个排名,以确定它们在用户界面中的显示顺序,即
Node 1 | Ranking = 10
Node 2 | Ranking = 11
Node 3 | Ranking = 12
Node 4 | Ranking = 13
Node 5 | Ranking = 14
我们的Node聚合有一个不变量,它规定排名不能低于特定值(让我们称之为10)。如果将排名设置为低于此值,则会导致重新计算所有兄弟节点(包括相关节点)。为了简单起见,假设计算只是基于兄弟姐妹排名的两倍来计算排名
Node 1 | Ranking = 9 (cannot be accepted, reset to 50)
Node 2 | Ranking = 100
Node 3 | Ranking = 200
Node 4 | Ranking = 400
Node 5 | Ranking = 800
关键是,针对一个聚合的命令会导致对另一个聚合(或在这种情况下为多个)的更改。
到目前为止采取的方法是在通往域的途中拦截这些命令,"修复"他们和然后发送它们。所以在上面的示例场景中
ChangeNodeRankingCommand
这很好,但有一些问题
选择这样做的原因纯粹是从查询的角度来看,我们在域中使用Event Sourcing因此加载相关的聚合并不是微不足道的(鉴于其性质)我们的活动商店。)
这是一种合理的方法,还是我完全错过了一招?
答案 0 :(得分:3)
乍一看(鉴于节点/排名内容很可能是简化的),似乎您的“排名”属性的聚合边界可能会被错误放置,特别是如果一个节点的排名影响其排名兄弟姐妹,明显越过AR边界。
在典型的树结构中(在数学意义上),所有兄弟姐妹的父可被视为负责其子女的排序。在此模型中,如果您随后向这些孩子的父母发送ChangeNodeRankingCommand
,则所有孩子的重新排名都会在AR上进行。
如果“排名”具有更复杂的含义,您可以尝试将父节点中的排序与具有传奇的各个节点的“排名”属性解耦(即,每当发送重新排序命令时)排名变化)。