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

时间:2015-08-12 12:08:32

标签: c# domain-driven-design aggregateroot

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

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

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

这是DDD有效的方法,让我们说聚合根“文件夹层次结构”,其中包含1个“文件夹”实体(即该文件夹层次结构的“标题”文件夹),每个文件夹实体都有0..N文件夹实体(子文件夹)

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

Is Aggregate Root with Deep Hierarchy appropriate in DDD?

Effective Aggregate Design by Vaughn Vernon

有关如何使DDD有效且有效的任何建议吗?

修改

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

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

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

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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

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

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