【问题标题】:Is it OK to compose an aggregate with immutable data from another aggregate?可以用来自另一个聚合的不可变数据组成一个聚合吗?
【发布时间】:2019-07-05 23:39:45
【问题描述】:

如果一个聚合需要一些不属于自己的只读数据来执行操作,那么让存储库从另一个聚合中查询一些数据来创建聚合有什么负面影响吗?

详细说明:

我有一个包含两个聚合的 BC,比如 ABB 需要来自A 的一些数据来执行一些操作,但不会以任何方式修改它。数据更适合A,因为有修改它的规则。

读取 DDD 的 IDDD 和 PPP 似乎可以将聚合(或其子实体)的临时引用传递给另一个,或者将只读视图作为值对象传递给另一个聚合。

在我的示例中,B 不需要整个 A 聚合,而只需要一些特定数据,因此在这种情况下,值对象似乎是一个好方法。 A 可以创建作为工厂的 VO,VO 将符合 UL,B 根本不需要了解 A。应用层的业务用例可以从仓库中重构AB,告诉A创建VO,并对传递VO的B执行操作。

现在让我们假设 A 的重构成本很高,或者还有另一个原因是不希望加载整个 A 以仅使用一点信息来创建 VO(可能数据不是来自一个实例A,但从它们的列表或其他列表中聚合)。这里有一个简单的解决方案,可以让A 的存储库直接从数据存储中创建 VO。我对此感到满意,并且似乎这是一种常见的模式。

但现在我在考虑B 上的操作执行多次的情况,或者可能是许多其他操作需要的B 上更大计算的一部分。我可以使用所需数据引用 VO(作为 B 或其图表中某处的私有只读属性),并让 B 的存储库获取创建 VO 所需的数据并重构 @ 987654343@ 与它。现在B 将始终拥有本地 的数据来执行其操作。取自A的数据不能修改;通过其存储库保存 B 只会丢弃该数据(也许它可以使用它来检测冲突的并发更新),AB 不会始终保持一致,但没关系,然后重新加载 B from如果发生冲突,存储库将再次查询数据以更新 B 内的视图。

这种方法对我来说似乎没问题,因为据我了解,域模型与数据模型无关,存储库充当两者之间的一种 ACL。 A 内部的数据也有一个单一的事实来源,因为B 内部的副本是不可变的并且最终是一致的。我看到的缺点是存储库将具有更多逻辑(但不是业务逻辑),并且可能不清楚数据的确切来源,因为从 BA 的依赖关系现在隐藏在基础设施代码中。

所以问题是:

  1. 毕竟这是一个不太好的方法吗?
  2. 还有其他我没有看到的缺点吗?
  3. 您或其他人是否做过类似的事情,以便我可以从那次经历中学习?

我知道这个例子很糟糕,因为在 DDD 中一切都是关于上下文的。但这是我在不同情况下多次提出的问题。我也知道一个有效的担忧是聚合边界是否明确定义,但假设它们看起来很适合手头的问题。

【问题讨论】:

    标签: oop domain-driven-design


    【解决方案1】:

    是否可以让存储库从另一个聚合中查询一些数据来创建聚合?

    Acceptable 的定义有点微弱。一个更好的问题可能是“有负面影响吗?”

    在这个例子中,通常的考虑是系统是否变得更难改变。看看 Adam Ralph 在 service boundaries 上的演讲,了解当您不控制组件之间的耦合时会发生什么。

    如今,如果 B 需要 A 数据的副本,那么我们通常会在 B 的设计中引入 A 数据的缓存。将数据副本与 B 一起存储,并明确计算出对 A 的更新如何以及何时传递给 B。缓存成为 B 数据模型的一部分。

    另请参阅 Pat Helland 的论文:Data on the Outside versus Data on the Inside.

    【讨论】:

    • 你说得对,“是否有负面后果”比“可接受”要好,我会编辑这个问题。英语不是我的母语,有时我想不出更好的表达方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 2019-02-13
    • 1970-01-01
    • 1970-01-01
    • 2019-08-07
    • 1970-01-01
    • 2016-05-10
    相关资源
    最近更新 更多