2

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

假设公司和个人都具有相同的邮件地址。这些陈述中哪些认为有效?

   1.“如果我修改 Company.Address,我希望 Person.Address 自动获取这些更改”

   2.“如果我修改Company.Address,它一定不会影响Person.Address”

如果 1 为真,地址应该是一个实体

如果 2 为真,地址应该是一个值对象。

在上面的模型中,邮件不Address应该是一个值对象,因为即使CompanyPerson相同的邮件,这封邮件仍然没有概念身份?

换句话说,如果最初CompanyPerson共享initial.address@gmail.com,然后得到新邮件new.address@gmail.com,那么我们可以说邮件地址 initial.address@gmail.com本身没有改变,而是Company并将Person其替换为new.address@gmail.com

因此,据我了解,一个共享的事实Address不足以赋予它个性(即身份)?!

谢谢

4

3 回答 3

7

是的,你的理解是正确的。地址几乎总是一个值对象,因为在大多数域中,地址确实只是一个值。

一个公司和一个今天拥有相同的地址这一事实并不意味着如果一个人发生变化,另一个人也应该改变。如果存在这样的关系,它应该通过显式约束而不是通过将Address设为实体来建模。

Eric Evans 在他关于域驱动设计的优秀著作中谈到了这一点,甚至还提供了一个具体的例子,地址可能是一个实体——邮政服务,其域围绕地址展开,并且单个地址的身份很重要。

于 2012-07-12T05:21:57.097 回答
1

实际上,邮件具有概念上的身份。问题是您并没有真正建模电子邮件地址,而是一个人的联系信息和/或公司的联系信息。继续这个话题,值对象与身份对象更多的是实现决策,而不是“绝对真理”。

您可以使用不可变的值对象,当您告诉系统“将地址 a 更改为地址 b”时,搜索个人和公司中地址 A 的所有实例,并立即更新它们以指向地址 b。(或者你可以只更新其中一个)。

使用非值联系信息对象更强大。和:

Contact Information
{
    string email;
}

实际上,您可以让个人和公司都指向同一个联系信息对象,因此当您更新一个时,您也会更新另一个。或者您可以让它们中的每一个指向不同的联系信息对象,因此当您更新一个时,您不会修改另一个...

顺便说一句:电子邮件具有概念上的身份,因为更改电子邮件地址实际上是谷歌上周对我所做的,当时他们将我的电子邮件地址从以@googlemail.com 结尾更改为@gmail.com ......所以如果有人同时拥有我和我公司的电子邮件,则只需一次更新就可以更改两个实例,因为在那种情况下,我的电子邮件地址会自行更改...如果另一方面,我开始使用不同的电子邮件地址,我的联系信息有什么变化......我的旧电子邮件地址仍然存在并且是相同的。

我的建议是使用标识对所有内容进行建模,除非它是一个非常好的域对象,您希望出于任何原因(例如数字、字符串等)将其优化为值对象的使用。但请记住,这通常是一个实施决定,而不是领域的决定。

于 2012-07-11T21:49:16.187 回答
1

这是一个断章取义的经典案例。

最初的问题(值对象如何存储在数据库中)并没有质疑模型的有效性,我的示例也没有突出这些问题。我的回答是关于Persistence vs Entity/VO

我使用了 、 和 的示例,Customer纯粹是为了与 OP 共享相同的通用语言(我没有时间想出更好的示例)。PersonAddress

我会听从卡萨布兰卡对此的建议(赞成)

于 2012-07-13T09:07:08.107 回答