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

How to define DDD Aggregate root for hierarchical data structure?

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

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

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

假设聚合根 "Folder hierarchy" 包含 1 个 "Folder" 实体(即该文件夹层次结构的 "header" 文件夹)和每个文件夹实体有 0..N 个文件夹实体(子文件夹)

那是有效的 DDD 吗?那会有效果吗?因为我读过 DDD 提倡有小聚合,但是这个 "Folder Hierarchy" 可能是一个巨大的聚合...

Is Aggregate Root with Deep Hierarchy appropriate in DDD?

Effective Aggregate Design by Vaughn Vernon

有什么建议可以使 DDD 既有效又有效吗?

编辑

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

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

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

您应该围绕不变量对聚合进行建模。一个经验法则是聚合应该一次性加载到内存(及其所有子对象),而不是延迟加载。

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

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

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

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

然后您的存储库将只获得具有所有祖先的任务,并且聚合将足够小。

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