在DDD中,如何处理实体和值对象之间的概念对象?

时间:2015-04-22 17:11:23

标签: entity domain-driven-design value-objects

在您的域模型中,您如何处理实体和值对象之间的概念对象?即,它不是;它有许多属性,但它本身也没有任何身份或意义(即,相等是基于属性)。因为它需要通过UI编辑其属性,所以我无法看到它是如何变为不可变的 - 每次用户更改属性时不断被销毁和重新创建。此外,该混合对象旨在成为一种或另一种类型的实体,这取决于其在系统中的作用。

示例:Recipe类。其目的是封装一组由机器执行的指令。如果两个不同的配方对象的集体指令相同则相同。配方旨在在系统中承担两个实体角色:

  1. 用于MasterSequence,这只是食谱列表 按顺序执行的对象。在这种情况下 Recipe在概念上会采用诸如的附加属性 StepNumberIsActive。这些收件人中的每一个现在带有一个 身份(即步骤1中的配方可能具有相同的属性 对于步骤2中的那个,但它们在概念上是截然不同的。)
  2. 食谱可以保存为"收藏食谱"这是持久的 收藏清单。在这种情况下,Recipe没有StepNumber的概念 或IsActive,而是一个简单的ID,赋予它身份。
  3. 在这两个角色中的任何一个中,UI都需要提供一个对话框来编辑基础配方的属性。 那么应该创建两个实体,SequencedRecipeFavoriteRecipe作为Recipe对象的包装器吗?如果Recipe具有值对象的所有语义,考虑其大小/复杂性和编辑需求,是否应该?

2 个答案:

答案 0 :(得分:2)

我认为你错过了无处不在的语言中的某些东西来区分配方的想法,即它的蓝图,以及在MasterSequence中执行的真实配方。 /秒>

Prototype的概念(以及design pattern同名)可能对此有所帮助。

RecipePrototype实体可以在需要时生成新的Recipe VO。然后,此VO将合并到MasterSequence中 - 这样,如果原始配方蓝图发生更改,则不会影响使用此配方的现有MasterSequences

public class RecipePrototype {

  // all your recipe fields here

  public Recipe spawnRecipe() {
    // copy yourself and return a new Recipe VO here
  }
}

收藏食谱只是对RecipePrototype ID的引用。

来自最新评论的

修改我现在意识到Recipes中包含的MasterSequence不是具有自己生命的特定食谱,而是原始{ {1}}对象始终是被修改的内容。

因此,Recipe显然是我的实体,没有涉及任何值对象修改。

这成为一个UI问题 - 您只需要有两个不同的ViewModel(RecipeMasterSequenceRecipe)进行显示,但在修改时映射到相同的域操作 - 更改{{1}实体。

答案 1 :(得分:1)

我实际上认为Recipe是一个实体,因为它听起来确实有一个身份。你说如果2个食谱具有相同的值,那么它们是相同的。然后你谈到在UI中编辑这些食谱。你会如何参考更新的食谱?我怀疑你会更新系统中匹配所有相同属性的任何随机配方。听起来你需要某种食谱ID,因为你确实关心哪个食谱被编辑,即使这些属性恰好相同。最喜欢的食谱也会简单地通过ID引用食谱,或任何其他具有与之相关的配方或食谱序列的实体。