DDD:我需要多少个聚合根?

Posted

技术标签:

【中文标题】DDD:我需要多少个聚合根?【英文标题】:DDD: How many Aggregate roots do I need? 【发布时间】:2016-11-29 11:05:22 【问题描述】:

我对 DDD 中的聚合根概念有点困惑。理论告诉它应该是与当前操作相关的聚合根。

例如,我有一个代表公司的根帐户。它具有地址、属于该帐户的用户、其他一些属性。

我有好几页;一种是管理一般信息,例如姓名、电子邮件、电话... 另一个是维护地址。 另一个显示所有用户(并编辑用户信息,可能也在 Account 对象下)

在第一种情况下我不关心地址,在第二种情况下我不关心姓名、电子邮件......

我需要两个单独的帐户对象还是只需要一个帐户? (模型可能比我描述的更复杂)

因此,例如,我最终可能会得到以下类:BasicAccountInformation、AccountAddress、AccountUsers.... 还是只有一个:包含所有数据的帐户?

什么是正确的 DDD 方法?我认为,在一种情况下,我会得到一个非常复杂的类,其中包含许多属性和逻辑;或者很多简单的类,每个类有 2-10 个属性。

【问题讨论】:

也许你应该考虑你的有界上下文... 我想你会发现我的Aggregate Explained 三部曲对你的问题很有用。长话短说,每个业务案例都应该有一个聚合及其根。您可以拥有(您应该拥有)多个代表同一概念的聚合,每个涉及该概念的命令业务案例一个聚合 感谢 MikeSW,博客文章使这个主题更加清晰。 【参考方案1】:

我需要多少个聚合根?

至少一个。

聚合用作一致性边界。如果您将整个域建模为单个聚合,并提供一个“聚合根”以确保每次写入都维护您的业务不变量,那么您就可以开始了。

嗯,你可以慢慢来。聚合根充当聚合边界中所有状态的一种序列化瓶颈。如果您希望“同时”更新模型的两个不同部分,那么您将需要划分业务不变量的责任。

我有两页;一个是管理一般信息,例如姓名、电子邮件、电话……另一个是维护地址。

报告很棒。它们会告诉您需要为模型收集哪些数据。

但是报告在告诉您聚合在哪里方面很糟糕 - 聚合的主要关注点不是读取/呈现/报告您的数据,而是写入数据。

您可以通过查找模型上的数据来查找聚合,这些数据在执行写入时需要组合在一起。您需要哪些数据来执行业务不变量?

这种启发式方法往往会吸引 CRUD 域,因为您的模型的大部分状态都独立于其余部分。

可以查看实体关系;如果两个聚合“共享”一个实体,则该实体可能属于第三个聚合。

您可以查看的另一件事是实体生命周期。如果一个子实体的寿命比聚合根长,那么你就知道你建模错了。

根据您的描述,这也无济于事;您实际上已经获得了帐户,以及其中包含的大量内容。

有时所有这些都失败了,您最终会使用启发式“我只想偶尔加载一次哪些数据”,然后您只需将其添加到键值存储中,然后返回交付业务价值。

【讨论】:

据我了解,当我只需要读取数据时,我不需要聚合根并且可以返回部分填充的对象,例如 Account GetBasicAccountInformation(accountid);帐户 GetAccountWithAddress(accountId);或者当你提到报告时,它应该是完全不同的对象?不是 Account,而是 AccountBasicInfoDto、AccountAddressDto? 使用 DTO,而不是域对象。

以上是关于DDD:我需要多少个聚合根?的主要内容,如果未能解决你的问题,请参考以下文章

DDD中聚合聚合根的含义以及作用

DDD的思考

DDD—聚合和聚合根

DDD 通过复合身份导航到聚合根内的实体

DDD关键知识点整理汇总

DDD领域驱动设计实战-聚合(Aggregate)和聚合根(AggregateRoot)