价值对象在数据库中如何存储?

78

我并没有见过具体的例子,但我认为它们保存在数据库中包含实体表内。

比如说,如果我有一个名为Person的实体/聚合根以及相应的Person表,如果它有一个叫做Address的值对象,那么Address的值将保存在这个Person表中!

对于一个拥有其他实体(例如公司等)都有地址信息的领域,这种方法是否适用呢?

(我正在编写一个项目管理应用程序,并试图学习DDD)

2个回答

154

根据您所描述的原因,将值对象(Value Objects)存储在单独的表中是可以的。然而,我认为您可能对实体(Entities)与值对象(VOs)的区别有些误解 - 这与持久性无关。

举个例子:

假设一个公司(Company)和一个个人(Person)都有相同的地址(Address)。下面哪种说法您认为是正确的?

  1. "如果我修改了公司的地址,我希望个人的地址也会自动更新"
  2. "如果我修改了公司的地址,个人的地址不应该受到影响"

如果1是正确的,那么地址应该是一个实体,因此应该有它自己的表格。

如果2是正确的,那么地址应该是一个值对象。它可以作为父实体表格中的组件进行存储,或者可以拥有自己的表格(更好的数据库规范化)。

正如您所看到的,地址的持久化方式与实体/值对象语义无关。


2
我可以问一下,如果我们坚持第二种情况,即使用VO但必须使用单独的表,因为它是VO的集合。那么在这个例子中,VO(地址)将具有包含实体的外键,并且在数据库中将具有一个键!这违反了值对象不应该具有身份的原则。 - Anyname Donotcare
非常感谢。但是如果我们忘记了“DB”,我能问一下,当我设计领域时,让VO集合与实体的实现有何不同吗?我必须为此集合创建一个类,该类将具有实体的键和ID。 - Anyname Donotcare
1
@任意名字别在意 不要将实体/值视为表格,你可以将带有所有值对象的实体作为单个文档存储在MongoDB中,或者将其作为带有子节点的单个节点存储在XML中,或者作为JSON对象存储。不要将逻辑和领域模型耦合到技术表示上。 - kravemir
@Vijay,你有实际的例子来说明如何实现吗?考虑到表格最终需要原语来存储,把地址作为非表格可能会有点混淆。你的意思是在仓库中,我们应该对值对象进行编码/解码并相应地持久化吗? - Ayyappa
@任意名称不在乎 是的,但是Address将在表中具有键,但不在域逻辑中。我认为重要的是它们在域逻辑内部没有身份标识。正如kravemir所说,数据库是技术细节。 - scovic

26

大多数开发人员在处理问题时往往优先考虑数据库。而领域驱动设计并不关心持久化的处理方式,这是由存储库来处理的。您可以将其持久化为xml、sql、文本文件等。实体/聚合根/值对象是与领域相关的概念。

Vijay Patel 的解释非常完美。


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