Domain driven design 域驱动设计中实体的每个属性都是值对象吗?

Domain driven design 域驱动设计中实体的每个属性都是值对象吗?,domain-driven-design,Domain Driven Design,我正在阅读“领域驱动设计的模式、原则和实践”。这本书建议一个实体的属性应该是值对象,以便为域的泛化语言建模。我见过很多例子,比如EmailAddress或Age,它们只有一个字段来建模域概念。我对此感到困惑。实体的每个属性都是值对象吗?当我们可以使用普通语言为属性提供的数据类型时,您能提供一些例子吗?我认为您真正的问题是:每个值对象都是一个类吗? 因为你可以认为在这个时代,一个Java整数就足够了,这是真的。因此,您的实体Person中有一个Integer类型的值对象Age,不需要Age类型 O

我正在阅读“领域驱动设计的模式、原则和实践”。这本书建议一个
实体的属性应该是值对象,以便为域的泛化语言建模。我见过很多例子,比如
EmailAddress
Age
,它们只有一个字段来建模域概念。我对此感到困惑。
实体的每个属性都是值对象吗?当我们可以使用普通语言为属性提供的数据类型时,您能提供一些例子吗?

我认为您真正的问题是:每个值对象都是一个类吗? 因为你可以认为在这个时代,一个Java整数就足够了,这是真的。因此,您的实体Person中有一个Integer类型的值对象Age,不需要Age类型

OOP还说对象是状态+行为。在您这个年龄的情况下,我假设它没有行为,所以一个简单的原语或包装器类就可以了,事实上我会选择这个选项,因为它更简单


我的建议是,使用一个基元/包装类,如果您注意到该值对象中需要某些行为,则创建一个类/类型。

不,不是实体的每个属性都是值对象。

实体的属性是以下属性之一:

  • 如您所知,对对象进行估价。值对象表示没有标识的简单值
  • 基本体。实际上,从DDD的角度来看,这些只是价值对象。原语可以在DDD中使用,但请注意不要成为DDD的受害者
  • 实体。一个实体可以包含其他实体。在它们之间具有直接(可导航)引用的所有实体都是相同的聚合的一部分。聚合中的“最顶端”实体称为聚合根。只有根具有全局标识,内部实体只有局部标识
  • 对其他集合实体的引用。永远不要直接引用这些,使用ID。ID本身可以作为值对象建模

您永远不必使用值对象而不是原始值,但滥用值对象肯定比使用相反的值要好。如果您认为一个字符串足以表示一个非常好的业务概念。@MajidAzimi我认为行为/验证将形成一个更好的指南。例如,
Age
在任何上下文中都不能为负值,必须为整数值。将该约束封装在
Age
value对象中是有意义的。我认为验证不足以证明类的合理性。实体必须作为一个整体有效,此验证还验证集成根实体的值对象。当验证年龄的轮到到来时,它将是一个简单的>0或JSR 303注释。@gabrielgiussi验证注释在域中没有它们的位置,这是用于视图模型的。模型应该没有任何类型的基础设施依赖关系。不要忘记DDD的本质是无处不在的语言,而不是技术实现<代码>年龄
是一个商业概念,有围绕它的规则。
Age
的不变量与它所关联的实体无关。例如,你可能有一个
Age
概念来防止负值,但有一个
Person
实体来防止年龄超过125岁。明确的成本是不到或很少的,这样设计会更加灵活。例如,如果
Age
在设计的其他地方也需要一个概念呢?在这一点上,你将不得不提取VO中的规则,然后更改合同。是的@plalx,我同意在某些情况下,单独的类是一个很好的选择,显然每种情况都必须进行适当的评估。我的建议是从这个角度出发