首页 > 解决方案 > 插入和删除的不同聚合根

问题描述

想象一下,我们有以下内容aggregate root

public class Resource
{
   public IEnumerable<Schedule> schedules {get;private set;}
   ...
}

当我们想添加一个新的时schedule,我们需要确保它不会与现有的冲突。这转化为aggregate root确保方法上的此不变量resource.AddSchedule(schedule)

另一方面,删除 aschedule没有不变量。如果我们使用Resource aggregate root删除一个schedule,我们需要预先加载所有schedules删除一个。

基于此,我们是否应该将 提升Scheduleaggregate root,只加载schedule我们需要的然后删除它?还是我们应该继续使用以前的aggregate root

标签: domain-driven-designaggregateroot

解决方案


当我们想要添加一个新的时间表时,我们需要确保它不会与现有的时间表发生冲突。

您在此处尝试实现的通用术语是set validation

如果您需要绝对保证集合中没有冲突条目,有时称为“立即一致性”,那么您必须保证条目不会与您的检查同时更改。这意味着您在检查中关心的值必须是检查它们的汇总的一部分——我们需要确保答案在我们下面不会改变。

更常见的情况是“尽力而为”就足够了,并且有一些协议可用于解决从裂缝中溜走的冲突。在这种情况下,您通常可以将集合视为标识符列表,而不是值列表。因此,详细信息可以保存在 Schedule 聚合中,而 Resource 聚合仅跟踪计划成员资格。

还有一个额外的极端情况——如果时间表是值而不是实体......意味着给定时间表的细节是不可变的,那么你也许可以吃蛋糕并吃掉它——为每个时间表计算一个唯一的哈希,并且将散列值存储在 Resource 中,以后可以在必要时用于查找不可变调度。

这里的很大一部分工作是正确获取业务需求的细节。在大多数成熟的业务领域中,冲突经常发生,以至于有解决它们的协议。换句话说,竞争条件不存在

时间上的微秒差异不应该对核心业务行为产生影响。


推荐阅读