在域模型中,如何处理介于实体和值对象之间的概念对象?即,它不是小;它有很多属性,但它本身也没有任何身份或意义(即平等是基于属性的)。因为它需要通过UI编辑其属性,所以我看不出如何使其不可变——每次用户更改属性时都会不断地被销毁和重新创建。此外,这个混合对象旨在成为一个一种或另一种类型的实体,这取决于它在系统中的角色。
示例:Recipe
类。它的目的是封装一组要由机器执行的指令。如果两个不同的配方对象的集体指令相同,则它们是相等的。配方旨在承担系统中的两个实体角色:
- 在
MasterSequence
中使用,CCD_2只是配方列表按顺序执行的对象。在这种情况下配方在概念上具有附加属性,例如3和CCD_ 4。现在,每一个这样的馅饼都有一个身份(即步骤1中的配方可能具有相同的属性与步骤2中的相同,但它们在概念上是不同的) - 配方可以保存为"收藏夹配方",并保存在收藏夹列表。在这种情况下,配方没有StepNumber的概念或者IsActive,而是一个简单的
ID
,赋予它身份
在这两个角色中的任何一个角色中,UI都需要显示一个对话框来编辑底层配方的属性。那么,是否应该创建两个实体,SequencedRecipe
和FavoriteRecipe
,作为Recipe对象的包装器?考虑到值对象的大小/复杂性和编辑需求,Recipe是否应该采用值对象的所有语义?
我认为您在无处不在的语言中遗漏了一些东西,无法区分配方的想法,即其蓝图,以及在
MasterSequence
中执行的真实配方。
Prototype的概念(以及同名的设计模式)在这里可能会有所帮助。
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的引用。
编辑:从最新的评论中,我现在意识到MasterSequence
中包含的Recipes
并不是一种有自己生命的特定配方,原始的Recipe
对象总是被修改的。
因此,Recipe
对我来说显然是一个实体,不涉及任何值对象修改。
这就变成了一个UI问题——您只需要有两个不同的ViewModel(MasterSequenceRecipe
和FavoriteRecipe
)来显示,但在修改中映射到同一个域操作——更改Recipe
实体。
我实际上认为Recipe是一个实体,因为它听起来确实有一个身份。你说如果两个食谱的值相同,那么它们是相同的。然后你谈到在UI中编辑这些食谱。你会如何参考更新后的食谱?我怀疑你会更新系统中任何匹配所有相同属性的随机配方。听起来你需要某种配方ID,因为你确实关心哪个配方被编辑了,即使属性恰好相同。最喜欢的配方也可以简单地通过ID引用配方,或者任何其他与之相关联的配方或配方序列的实体