DDD: 帮我更好地理解值对象和实体

6

有几个关于这个问题的问题,阅读它们并没有帮助我。在Eric Evans DDD中,他举了地址在某些情况下是值类型的例子。对于一个邮购公司来说,地址是一个值类型,因为地址是否共享,谁还住在这个地址上并不重要,重要的是包裹能够到达这个地址。

这对我来说很有道理,直到我开始考虑如何设计它。根据第99页的图表,他将其设计如下:

+------------+
|Customer    |
+------------+
|customerId  |
|name        |
|street      |
|city        |
|state       |
+------------+

这将变为:

+------------+
|Customer    | (entity)
+------------+
|customerId  |
|name        |
|address     |
+------------+

+------------+
|Address     | (value object)
+------------+
|street      |
|city        |
|state       |
+------------+

如果这些是表格,地址将拥有自己的ID以便与客户建立关系,从而将其转化为实体。
在关系数据库中,这些内容将保留在同一张表中,例如第一个示例中,您可以使用ORM的功能将地址抽象为值对象(例如nHibernate的组件功能)。
我意识到他几页之后谈到了去规范化,我只是想确保我正确理解了这个概念。
4个回答

8
当Eric Evans谈到“实体具有身份,值对象没有”时,他不是在谈论数据库中的ID列 - 他谈论的是作为概念的身份。
VO没有概念上的身份。这并不意味着它们不应该具有持久性身份。不要让持久性实现影响您对实体和VO的理解。
您可以为地址创建单独的表,也可以将其放在客户表中。

谢谢您的解释,它让我对在这种情况下使用DDD更有信心。 - jpierson

2

在关系型数据库中,这种情况就像第一个例子中一样,这些地址信息会保存在同一张表格中,并使用ORM的特性来将地址作为值对象进行抽象(例如nHibernate的component特性)。

是的,通常就是这么做的。

或者,如果你的ORM不直接支持值对象,你可以让值对象表格拥有一个ID,但在你的领域模型中隐藏掉它。


1

是的,通常地址会保留在同一张表中。地址将被映射为类似于以下内容:

+-----------------+
|Customer         |
+-----------------+
|customerId       |
|name             |
|address_street   |
|address_city     |
|address_state    |
+-----------------+

如果地址是一个实体,那么它应该在一个单独的表中,就像你所说的一样。如果两个相同的客户链接到同一个地址实体,则更改该地址的属性将影响两个客户。然而,VO实现只会影响其中一个。

1

个人而言,在值对象上有无标识符我并不在乎,只要它们适当地覆盖等式比较(因为值对象按其值而非标识符进行区分)。

将值对象映射到数据库是技术问题,有时(例如标记道具虚拟,以便ORM可以爬行底部),您只需要稍微牺牲一点域模型的纯度。或者让您的基础设施更加智能——使用nhib组件或类似组件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接