【问题标题】:DDD Value objectsDDD 值对象
【发布时间】: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 中更改名称,因为它是当时发行人的名称。
  • 那么你肯定必须在值对象中有一个名字。

标签: domain-driven-design


【解决方案1】:

"我倾向于第 2 号解决方案,因为如果发行人的名称 由于某种原因发生变化,我仍然会有发行人的名称 在创建发票时,以及对更改的发行人的引用 他的名字。”

您已经自己回答了这个问题。符合上述要求的唯一型号是#2。

您肯定可以努力遵循建模最佳实践(偏爱值对象、设计小型聚合等),但归根结底,DDD 是关于制作特定于领域的模型,这样的模型只能受到批评,而且只能在其问题域的上下文中具有价值。

当您寻求验证您的模型时,请首先关注业务行为和不变量。

【讨论】:

    猜你喜欢
    • 2012-08-24
    • 2010-10-31
    • 2014-06-03
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 2012-04-01
    • 1970-01-01
    相关资源
    最近更新 更多