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

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

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

我在一个文件夹上有不变量,所有它的直接和间接子文件夹 – 删除文件夹应该导致删除它的所有子文件夹

那将是DDD有效方法让我们说聚合根“文件夹层次结构”,它包含1个“文件夹”实体(即该文件夹层次结构的“标题”文件夹),每个文件夹实体具有0..N文件夹实体(sub -folders)

那是一个有效的DDD吗? 这会有效吗? 由于我已经读过DDD主张拥有小聚合,但是这个“文件夹层次结构”可能是一个巨大的聚合…

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

Vaughn Vernon的有效集合设计

任何建议如何使这两个DDD有效和有效?

编辑

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

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

根据DDD原则, Task的优秀设计是什么? 如果Task (带有它的层次结构)不是aggegate,如何在Task上实现不变量(包含所有它的子任务层次结构)?

您应该围绕不变量建模聚合。 一条经验法则是聚合应该一次性加载到内存中(包含所有它的子对象)没有延迟加载。

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

如果您需要所有数据,那么您的聚合具有适当的大小,它就不会更小。 如果你的不变量只需要图的一小部分,那么你可能会遗漏一些描述这个图形部分的域概念。

如果您只关心更新祖先的时间,那么您的任务可能只包含您不需要子集的父属性。 然后你可以执行类似的事情

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

然后你的存储库将只获得他所有祖先的任务,聚合将足够小。

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