如何建模域模型 - 聚合根

How to modelling domain model - aggregate root

我在正确设计我正在处理的域时遇到了一些问题。

我的直接用例如下:
用户(约 5000 名用户)可以访问广告列表(约 500 万)
他可以选择 add/remove 其中一些收藏。
他可以决定 show/hide 其中一些。

我有一个命令会改变聚合状态,比如说将收藏夹设置为 TRUE。

在DDD方面,我应该如何设计聚合?
如何设计用户与他喜欢的广告选择之间的关系?
考虑到大量广告,我无法在用户聚合根中复制每个广告。
我可以设计一个包含用户“collection”的 Ads aggregateRoot。

最后,如何 handle/perform readmodels 部分?

提前致谢

干杯

两个概念可以帮助您理解如何对此建模:

1.聚合是事务边界。

聚合是一组关联的 object,它们被视为一个单元。聚合的所有部分一起加载和持久化。

如果您有一个包含 1000 个实体的聚合,那么您必须将它们全部加载到内存中。因此,您最好尽可能使用小聚合体。

2。聚合是不同的概念。

聚合表示域中的一个不同概念。与多个聚合关联的行为(如收藏,在您的情况下)通常是一个聚合本身,具有自己的一组属性、域 objects 和行为。


根据您的示例,User 是一个明确的聚合。

一个Ad在域中有一个与之相关的独特概念,所以它也是一个集合。可能还有其他实体将嵌入广告中,例如 valid_untildescriptionis_active

收藏广告的概念链接了 UserAd 聚合。您的问题似乎集中在应该保留这种联系的地方。它应该在 User 聚合中(Ads 的列表),还是 Ad 应该嵌入 User object 的 collection在里面?

虽然两者都是可能的,恕我直言,我认为 FavoriteAd 是另一个聚合,它包含对 User 聚合和 Ad 聚合的引用。这样,您就不会因为偏爱行为而给 UserAd 的概念带来负担。

这些聚合也不需要在每次加载到内存时都加载这些额外数据。例如,如果您正在加载 Ad object 来编辑其内容,您不希望默认情况下将收藏夹 collection 加载到内存中。

就读取模型而言,这些聚合结构并不重要。聚合仅处理域的 write 端。您可以在 read 端以多种形式自由地以任何方式重新连接数据。您可以让订阅者只收听 Favorited 事件(在处理 Favorite 命令后引发)并构建包含来自 User 和 [=11= 的数据的复合数据结构]聚合。

我非常喜欢 Subhash Bhushan 给出的答案,我想添加另一种方法供您考虑。

如果您仔细查看您的问题,您会发现您假设聚合可以 'see' 用户在与 UI 交互时所做的一切。不必如此。

根据域的要求,您无需在聚合中保存任何广告的列表即可收藏它们。这就是我的意思:

对于此示例,'favourite' 广告命令位于何处并不重要。它可以在用户聚合或特定聚合上,用于处理收藏的概念。该命令只需要保存用户的 ID 和他们喜欢的广告。

您可能需要处理删除用户或广告时发生的情况,但这只是事件流程管理器侦听相应事件并发出补偿命令的情况。

这样您就不需要加载 500 万个广告。这是读取模型和 UI 的工作,而不是域。

只是一个想法。