如何为分层数据结构定义DDD聚合根

本文关键字:DDD 定义 数据结构 分层 | 更新日期: 2023-09-27 18:07:24

我目前正在尝试将领域驱动设计原则应用到我的开发实践中。我一直在讨论如何为在层次结构中组织的数据定义聚合根。

让我们以文件夹结构为例-每个文件夹可以有0..N个子文件夹,子文件夹0..N也可以是0。N个子文件夹,以此类推。

我有一个文件夹及其所有直接和间接子文件夹的不变量-删除文件夹应该导致删除它的所有子文件夹

这会是DDD有效的方法,让我们说聚合根"文件夹层次结构",它包含1个"文件夹"实体(这将是文件夹层次结构的"头"文件夹),每个文件夹实体有0..N文件夹实体(子文件夹)

这是一个有效的DDD吗?这有效吗?因为我读到DDD提倡有小的聚合,但这个"文件夹层次"可能是一个巨大的聚合…

在DDD中具有深层层次结构的聚合根是否合适?

Effective Aggregate Design by Vaughn Vernon

有什么建议如何使DDD既有效又有效?

<标题>编辑

让我们有一个不同的例子,具有树状结构的对象。假设我需要开发一个任务跟踪系统,该系统需要任务具有非固定级别的子任务深度-所有任务从功能/行为角度来看都是相同的-每个任务可以有0..1个父任务,0..N个子任务。

Task作为聚合根(所有它的子任务层次结构)不会遵循DDD建议的小聚合-对吧?

根据DDD原则,Task的良好设计是什么?以及如何实现Task上的不变量(与所有它的子任务层次结构),如果Task(与它的层次结构)不是一个聚合?

如何为分层数据结构定义DDD聚合根

应该围绕不变量对聚合进行建模。一条经验法则是,聚合应该一次加载到内存中(连同它的所有子对象),而不是延迟加载。

你真的有一个需要加载整个层次结构的不变量吗?是否存在需要遍历层次结构中的所有节点的情况?要回答这个问题,您需要考虑聚合的用例。

如果你需要所有的数据,那么你的聚合有适当的大小,它不能更小。如果你的不变量只需要图的一小部分,那么你可能缺少一些描述这部分图的域概念。

如果你只关心祖先的更新时间,那么也许你的任务可以只包含Parent属性,你不需要子属性收集。然后你可以执行

public void RegisterTime(TimeSpan time)
{
    TimeSpent += time;
    // maybe more stuff here
    Parent.RegisterTime(time)
}

那么您的储存库将只获得具有其所有祖先的Task,并且聚合将足够小。

我只是猜测,因为它总是取决于用例。