DDD:帮助我进一步了解价值对象和实体

时间:2011-02-15 21:22:00

标签: domain-driven-design

有几个问题,阅读它们并没有帮助我。在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 个答案:

答案 0 :(得分:8)

当Eric Evans谈到“实体有身份,Value Objects没有”时,他不是在谈论数据库中的ID列 - 他在谈论身份作为一个概念。

VO没有概念上的认同。这并不意味着他们不应该有持久性身份。不要让持久性实现让您了解实体与VO。

您可以为地址或客户

中的同一表创建单独的表

答案 1 :(得分:2)

  

是关系中的想法吗?   数据库这些将保持不变   表,例如在第一个例子中,   并且您将使用ORM的功能   将地址抽象为值对象   (比如nHibernate的组件   特征)?

是的,一般来说,就是这个想法。

或者(如果您的ORM不直接支持Value Objects),您可以让VO表具有ID,但在您的域模型中隐藏它。

答案 2 :(得分:1)

我个人不会在值对象上使用ID,只要它们正确地覆盖相等比较(因为值对象因其值而不同而不同)。

将值对象映射到数据库是技术问题,有时候(例如标记道具虚拟,因此ORM可以在下面爬行)你只需要牺牲一点领域模型的纯度。或者使您的基础设施更智能 - 使用nhib组件或其他东西。

答案 3 :(得分:1)

是的,一般地址会保留在同一张表中。地址将映射如下:

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

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