Domain driven design 在CQRS体系结构中如何处理命令端影响?

Domain driven design 在CQRS体系结构中如何处理命令端影响?,domain-driven-design,distributed,cqrs,Domain Driven Design,Distributed,Cqrs,我们开始在系统中发现一些场景,其中针对聚合的命令的结果可能会影响其他相关聚合 为了演示这个问题,考虑一个树结构,在这个结构中我们有兄弟姐妹节点。每个节点都有一个排名,以确定它们在UI中的显示顺序,即 Node 1 | Ranking = 10 Node 2 | Ranking = 11 Node 3 | Ranking = 12 Node 4 | Ranking = 13 Node 5 | Ranking = 14 我们的节点聚合有一个不变量,它规定排名不能设置为低于特定值(我们称之为10)。

我们开始在系统中发现一些场景,其中针对聚合的命令的结果可能会影响其他相关聚合

为了演示这个问题,考虑一个树结构,在这个结构中我们有兄弟姐妹节点。每个节点都有一个排名,以确定它们在UI中的显示顺序,即

Node 1 | Ranking = 10
Node 2 | Ranking = 11
Node 3 | Ranking = 12
Node 4 | Ranking = 13
Node 5 | Ranking = 14
我们的节点聚合有一个不变量,它规定排名不能设置为低于特定值(我们称之为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
关键是,针对一个聚合的命令会导致对另一个聚合的更改(在本例中是多个)

到目前为止所采取的方法是在到达域的途中拦截这些命令,“修复”它们,然后发送它们。在上面的示例场景中

  • 我们从客户端收到一个
    changenoderanking命令
  • 我们验证该命令,即它是否是新的排名在10以上
  • 如果命令有效,它将被发送到域
  • 如果命令无效,我们查询读取端以取出所有受影响的聚合ID
  • 我们使用调整后的排名为每个聚合(包括有问题的聚合)创建一个命令
  • 我们将这些命令发送到域并丢弃原始命令
这很好,但也有一些顾虑

  • 我们总是处理可能导致问题的过时数据(试图更新随后被删除的实体等)
  • 这些东西似乎是域逻辑,因此可能应该由域来处理
选择这种方式的原因纯粹是从查询的角度来看的,我们在我们的域中使用,因此加载相关的聚合并不简单(考虑到事件存储的性质)

这是一个合理的方法还是我完全忽略了一个技巧?

乍一看(考虑到节点/排名的内容很可能是简化的),您的“排名”属性的聚合边界可能被错误放置,特别是如果一个节点的排名影响其兄弟节点的排名,这显然跨越了AR边界

在典型的树结构(数学意义上)中,所有兄弟姐妹的父代可能被认为负责其子代的排序。在此模型中,如果随后向这些子级的父级发送
ChangeNodeRankingCommand
,则所有子级的重新排序将在AR中进行


如果“排名”的含义更为复杂,您可以尝试将父节点中的排序与各个节点的“排名”属性与saga分离(即,每当排名发生变化时发送重新排序命令)。

我知道这种方法不正确(因此提出了问题)。因此,不要为每个节点聚合使用单独的命令,而是向父节点发出单个命令,例如,
CalculateChildRankingsCommand
,然后在域中执行此操作?这是有道理的,唯一的缺点是我当前的设置不允许在写端使用这种类型的查询。实际上,我需要加载每个节点,然后按父节点过滤——我想这更像是一个设计问题。是的,这就是我的意思。至于查询问题,你当然也可以使用投影。当你说我可以使用投影时,你的意思是让写端查询读端吗?或者实际上在写端创建了投影?我对整个CQRS游戏还不熟悉,我发现最大的问题是,对于这类东西没有明确的规则。当前“我的域”只能单独加载聚合(它不能加载相关聚合)。如果父节点需要有其所有子节点的列表或某些信息才能执行其操作,例如,您可以向域层添加域服务接口,以允许父节点查询必要的信息。然后,这个域层可以通过读取模型(由投影支持)实现(在域层之外,就像存储库一样),这样这个查询速度很快,不需要涉及到的查询。那么这个域服务将查询读取端?这不正是我前面提到的问题吗?查询读取端意味着(可能)正在处理过时的数据?“阅读模型(由投影支持)”我现在有点困惑,阅读模型/投影不是一回事吗?