【发布时间】:2016-06-30 08:49:36
【问题描述】:
引用埃文斯蓝皮书
得知我们应该努力使用 尽可能使用值对象而不是实体。即使当一个 领域概念必须建模为实体,实体的设计 应该偏向于充当价值容器而不是 子实体容器。该建议并非基于任意 偏爱。衡量、量化或描述事物的价值类型是 更易于创建、测试、使用、优化和维护。
把它放在我的上下文中,我有
- 发票实体为 AR 的发票聚合
- 以发行人实体为 AR 的发行人聚合
每张发票都有其发行人。我应该通过 ID 将其视为 Invoice->Issuer 关系,还是将其视为具有对 Issuer 的引用的值对象,或者将此发行者简单地视为从 Issuer AR 创建的值对象是一种更好的做法
所以在这种情况下会是
1.
Invoice
-InvoiceId
-IssuerId
VS
Invoice
-InvoiceId
-InvoiceIssuer
-IssuerId
-FullName
VS
Invoice
-InvoiceId
-InvoiceIssuer
- Fullname
我倾向于使用第 2 号解决方案,因为如果发行人的名称因某种原因发生更改,我在创建发票时仍然会有发行人的名称,以及更改姓名的发行人的参考。
这背后的逻辑是,如果我尝试打印一张旧发票,在发行人更改姓名后,我仍然会有旧状态的发票,因为它最初是这样打印的,但如果我仍然会能够找到该发行人的所有发票,即使他改名了。
创建值对象是否通过 ID 有效方法引用另一个实体,或者在这种情况下我做错了什么?
【问题讨论】:
-
你的限界上下文在哪里?
-
退回的上下文是Accounting,它由Invoices、Reciptients、Issuers、VatTypes等组成。
-
在一个 BC 内我会使用 (2),否则使用 (1)。但是,问题仍然存在,您计划如何跨聚合更新名称。答案似乎很明显 - 只需使用域事件,直到您发现您有两个不同的聚合,并且从书上看,您的聚合就是事务边界。所以你有一些风险,一个聚合更新而另一个不更新。
-
名称更新是什么意思?我认为不应该在发票 VO 中更改名称,因为它是当时发行人的名称。
-
那么你肯定必须在值对象中有一个名字。