领域驱动设计——你能在不同的聚合根中使用简化的现有聚合吗

Domain Driven Design - Can you use a simplified existing Aggregate in a different Aggregate Root

我有一个名为 Survey 的聚合 - 您可以创建一个 Survey,发送一个 Survey 并回复 调查.

我还有一个名为 Person 的聚合。他们可以收到 调查 并回复 调查。此汇总包括描述 .

的人口统计信息

我认为我的调查汇总应该包含一份已接受调查的人员列表。这将包括他们收到邮件的日期以及他们的任何答复(如果他们已做出答复)。但我觉得我不需要大多数通常会随现有 Person 汇总一起提供的人口统计信息。

我尝试使用不同的概念,例如将发送称为“送货”,将员工称为“收件人”,但企业并没有用这些术语来表达。只是 - “我创建了一个 调查 ,然后我将那个 调查 发送给人们”。

那么在 调查 中创建一个不同的 Person 聚合有意义吗?向某人发送 调查 的操作作为记录存在于数据库中,以及对 调查 的响应。这是值对象的更好用例吗?

这是一个战略设计问题。

我认为你这里有两个限界上下文,所以你应该在它们之间拆分你的 Person 域模型。来自 调查上下文 的人将仅包含调查所需的数据和行为。另一个人(例如营销背景)涵盖了营销团队的需求。

这是来自 Martin Fowler's blogpost 关于 BC 的例子

所以你对其他聚合几乎是正确的,但它不是一个简化版本,它是一个单独的版本。

只要您使用诸如“我不需要所有...数据”或“就是这样,但有更多属性但不是这些原始属性”之类的短语,您就在隐含地引入这个概念实体从一个有界上下文到另一个有界上下文的投影

在你的情况下,PersonPerson 处于不同的有界上下文中进行调查(我将后者称为 SurveyParticipant) 因为虽然是同一个人参加调查,但两个实体的侧重点是不同的。

这是您的问题的可能解决方案(扩展了一点,仅供参考)。

人作为 SurveyParticipant 投射到 Survey Taking 有界上下文中。作为奖励,Survey 实际上是调查的定义,但是 SurveyInstance 是一个 Survey be/is 由这些 SurveyParticipants 进行。

SurveyParticipant 不是 PersonSurveyParticipant 是(将要)参与完成 SurveyInstance.

的人

底线,

Can you use a simplified existing Aggregate in a different Aggregate Root

是的。您可以通过将数据从一个聚合投影到另一个上下文中的实体来实现(至少在我提出的解决方案中)。

So does it make sense to create a different Person aggregate just within Survey?

有点。一个聚合永远不能包含另一个聚合,但它可以引用同一个有界上下文中的一个聚合。我没有在这个解决方案中这样做。如图所示,另一种方法是聚合可以包含来自另一个聚合的信息作为另一个聚合的投影。