有几个问题,阅读它们并没有帮助我。在Eric Evans DDD中,他使用地址在某些情况下作为值类型的示例。对于邮购公司而言,地址是一种价值类型,因为如果地址是共享的,那么其他人居住在该地址并不重要,只是包裹到达该地址。
这对我来说很有意义,直到我开始考虑如何设计它。鉴于第99页的图表,他就是这样的:
+------------+
|Customer |
+------------+
|customerId |
|name |
|street |
|city |
|state |
+------------+
这改为:
+------------+
|Customer | (entity)
+------------+
|customerId |
|name |
|address |
+------------+
+------------+
|Address | (value object)
+------------+
|street |
|city |
|state |
+------------+
如果这些是表格,地址将拥有自己的ID,以便与客户建立关系,将其转变为实体。
这个想法是在关系数据库中这些将保留在同一个表中,例如在第一个示例中,并且您使用ORM的功能将地址抽象为值对象(例如nHibernate的组件功能) ?
我意识到几页后他谈到非规范化,我只是想确保我正确理解这个概念。
答案 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实现只会影响其中一个。