Domain driven design DDD:引用非聚合根

Domain driven design DDD:引用非聚合根,domain-driven-design,Domain Driven Design,我正在尝试使用一些DDD概念来改进我的设计。目前我有4个简单的EF元素,如下图所示: 有多个任务模板每个模板都存储多个任务站点模板。TaskItemTemplates包含各种信息(说明、图像、默认处理时间) 用户可以基于任务模板创建新的具体任务。在当前的实现中,这还将为每个taskitemplate创建一个taskitemplate,但将来可能会选择一个相关的TasksItemTemplates 我想知道如何在DDD中建模这个需求。不允许从TaskTemplateItem引用到TaskTemp

我正在尝试使用一些DDD概念来改进我的设计。目前我有4个简单的EF元素,如下图所示:

有多个
任务模板
每个模板都存储多个
任务站点模板
TaskItemTemplates
包含各种信息(说明、图像、默认处理时间)

用户可以基于任务模板创建新的具体任务。在当前的实现中,这还将为每个
taskitemplate
创建一个
taskitemplate
,但将来可能会选择一个相关的
TasksItemTemplates

我想知道如何在DDD中建模这个需求。不允许从
TaskTemplateItem
引用到
TaskTemplateItem
,因为
TaskTemplateItem
不是聚合根。但如果没有此引用,则无法获取
TaskTemplateItem
的属性。 当然,我可以删除引用并将所有属性从
TaskTemplateItem
复制到
TaskTemplateItem
,但实际上我喜欢通过更新
TaskTemplateItems
来更新
TaskTemplateItems


更新:任务(项目)模板更新的预期行为 应该可以编辑
TaskTemplate
TaskItemTemplate
,例如,修复名称或描述中的打字错误。我希望这些更改会反映在
任务/TaskItem
中。 另一方面,如果修改了DefaultProcessingTime,则不应更改TaskItem的持久DueDate

在我当前的实现中,无法将
taskitemplates
添加/删除到持久化的
TaskTemplate
,但这将是一个很好的改进。我如何实现这样的东西?在
TaskTemplate
TaskTemplate
之间添加另一个实体
TaskTemplateVersion

Update2:TaskItemTemplateId作为ValueObject 在再次阅读沃恩的幻灯片后,我认为通过简单的修改,根据DDD,我的模型是正确的:

不幸的是,我真的不明白,为什么这个设计更好(是不是更好?)。好的,TaskItemTemplates不会有不必要的db查询。但另一方面,在处理TaskItem时,我几乎需要TaskItemTemplate,因此一切都变得更加复杂。我再也不能做这样的事了

public string Description
{
  get { return this.taskItemTemplate.Description; }
}

根据您在
taskitemplate
taskitemplate
下面列出的属性,我认为它们应该是值对象而不是实体。因此,如果没有理由(根据您问题中的信息,没有理由)使它们成为实体,请将它们更改为不可变值对象

使用该解决方案,您只需通过复制其数据,从
TaskItemTemplate
创建一个
TaskItem

关于您描述的更新场景,请参见以下解决方案:

  • taskitemplate
    是从特定版本的
    taskitemplate
    创建的。用
    任务项
    记录该版本
  • TaskTemplate
    负责更新其项目并跟踪其版本
  • 如果模板发生更改,如果需要立即执行操作,请通知从模板派生的所有任务。如果您只是希望能够在以后“拉入”模板更改(而不是在模板更改时执行操作),则只需比较版本
要做出明智的决策,充分理解不变性的利弊是非常重要的。只有这样,您才会看到将事物建模为价值对象的好处。关于这个话题,我觉得很有价值的一个来源是


此外,沃恩·弗农(Vaughn Vernon)的《实现DDD》一书很好地解释了价值对象和实体的概念。

顺便说一句,不要将DDD实体与EF实体混淆。我知道在完美世界中,DDD和EF之间存在差异。但也有相当多的人试图将DDD概念直接应用于EF。我使用的是直接基于实体生成的视图。因此,不可能开发一个真正的DDD解决方案,但我认为仍然可以用它改进我的设计。@krombi您能再解释一下当
TaskItems
TaskItemTemplate
被修改时,您对
TaskItems
的预期结果吗?我首先更新了我的问题:谢谢!但我真的对DDD感到困惑。虽然ValueObjects/Entities的概念乍一看似乎很简单,但你可以在这方面找到很多不同的观点。TaskItem:具有可更改的TaskStatus。因此它是一个实体,不是吗?TaskItemTemplate:是否可以收集VO?有些人说不行。复制创建方法:是的,这应该行得通。TaskItemTemplate还存储图像属性。我真的应该复制这个图像多次吗?我非常喜欢DDD的想法,但有时很难离开以数据为中心的/DB/CRUD方式。是的,如果TaskItem需要可变,它不能是值对象。但这会使您的设计变得更加复杂。您可以尝试在任务中而不是在项目中管理任务状态。不过,我不知道这在你的申请中是否有意义。为什么不能列出VO?那太可笑了。您可以创建数字列表,毕竟:-)。VO(或者更确切地说是不可变对象)的好处是它们可以共享(因为它们保证不会更改),所以您不需要复制映像。我不理解为什么如果TaskItem是可变的,设计会变得更复杂。你能详细说明一下吗?我看到的一个问题是:不可能共享TaskItem实体,例如,经理无法监视一组特定的TaskItem,因为它们属于不同的AR。可以监视ValueObject。令人困惑反对VO列表的论点:如果我愿意