Domain driven design 插入和删除的不同聚合根

Domain driven design 插入和删除的不同聚合根,domain-driven-design,aggregateroot,Domain Driven Design,Aggregateroot,假设我们有以下聚合根目录: public class Resource { public IEnumerable<Schedule> schedules {get;private set;} ... } 公共类资源 { 公共IEnumerable时间表{get;private set;} ... } 当我们想要添加一个新的计划时,我们需要确保它不会与现有计划冲突。这意味着在resource.AddSchedule(schedule)方法上使用聚合根确保该不变量 另一方

假设我们有以下
聚合根目录

public class Resource
{
   public IEnumerable<Schedule> schedules {get;private set;}
   ...
}
公共类资源
{
公共IEnumerable时间表{get;private set;}
...
}
当我们想要添加一个新的
计划时,我们需要确保它不会与现有计划冲突。这意味着在
resource.AddSchedule(schedule)
方法上使用
聚合根
确保该不变量

另一方面,删除
计划
没有不变量。如果我们使用
资源聚合根
删除
计划
,我们需要先加载所有
计划
,只删除一个


基于此,我们是否应该将
计划
提升为
聚合根
,只加载我们需要的
计划
,然后将其删除?或者我们应该继续在实践层面上使用前面的
聚合根目录

,以下哪两项更可能引起用户的关注

  • 尝试删除计划时,应用程序太慢
  • 我们希望在删除计划时应用规则X
就我个人而言,我会避免过早的优化,这可能会让你在未来陷入困境

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

一般来说,你在这里想要达到的目标是

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

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

还有一个额外的情况--如果明细表是值而不是实体。。。这意味着给定计划的细节是不可变的,那么您也可以吃蛋糕了——为每个计划计算一个唯一的散列,并将散列值存储在资源中,以后如果需要,可以使用它来查找不可变的计划

这里的大部分工作是获得正确的业务需求细节。在大多数成熟的业务领域中,冲突经常发生,因此有解决冲突的协议。换句话说

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

基于此,我们是否应该将计划提升为聚合根

如果
计划
有自己的生命周期,那么它在任何情况下都需要是一个集合,这将稍微改变您的设计

但是,假设
资源
->
计划
订单
->
订单项
之间的关系相同,则您可以始终让存储库为
计划
公开更简单的删除操作:

public interface IResourceRepository
{
   void Add(Resource resource);
   void RemoveSchedule(Resource resource, Resource.Schedule schedule); // or some such
}
对于
顺序
来说,考虑到可能存在相关的不变量,这可能不起作用

更新

如果您的
计划
是一个聚合根,那么您可能会在
资源
之前独立创建它。
时间表的唯一性将属于@VoiceOfUnreason提到的集合验证的范围。然后,您的
资源
仍然需要对
计划
实例的引用列表,但这些引用可能只是
Id
或某个值对象包含
Id
和任何其他相关位。确保您没有重复的计划将是
资源执行的一项不变的任务

为了从资源中删除计划,您将返回到第一个选项:要么加载
资源
,然后删除相关的计划
Id
,要么直接通过存储库删除它


始终存在硬删除与软删除的问题,通常只应更改状态(软删除),因为问题较少。硬删除
计划
可能会被数据存储上的DRI停止(如果配置)或者将删除内容级联到相关表。

Gotcha!在进行DDD时,我们需要修改datatabase驱动的思维。@PedroFaustino这是第一个挑战之一,但一旦你摆脱了这种束缚,你就会意识到一切都取决于需求。跳转到db模式设计很容易,但这通常不是价值所在是。考虑到计划有自己的生命周期,并且被提升为AR,我如何确保一个资源不能同时有两个计划?