如何建模领域模型-聚合根

时间:2020-09-30 16:18:35

标签: aggregate domain-driven-design cqrs aggregateroot

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

我的简单用例如下:
该用户(约5000个用户)可以访问广告列表(约500万个)
他可以选择添加/删除其中一些作为收藏夹。
他可以决定显示/隐藏其中一些。

我有一条命令会改变聚合状态,比如说将Favorite设置为TRUE。

就DDD而言,应该如何设计聚合?
如何设计用户与其最喜欢的广告选择之间的关系?
考虑到广告数量众多,我无法在用户聚合根目录内复制每个广告。
我可以设计一个包含用户“集合”的Ads AggregationRoot。

最后,如何处理/执行readmodels部分?

预先感谢

欢呼

2 个答案:

答案 0 :(得分:2)

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

1。汇总是交易边界。

集合是关联对象的群集,被视为一个单元。聚合的所有部分均已加载并保持在一起。

如果聚合包含1000个实体,则必须将所有实体加载到内存中。因此,您最好在可能的情况下最好使用较小的聚集体。

2。聚合是不同的概念。

集合表示域中的不同概念。与多个聚合相关联的行为(例如您的收藏夹行为)通常是具有其自身的一组属性,域对象和行为的聚合。


在您的示例中,User是明确的汇总。

Ad在域中具有与之相关的独特概念,因此它也是一个聚合。可能还有其他实体会嵌入到广告中,例如valid_untildescriptionis_active等。

收藏广告的概念将UserAd聚合链接在一起。您的问题似乎集中在应保留此链接的位置。它应该是User聚合(Ads的列表),还是应该在Ad中嵌入User个对象的集合?

虽然两者都有可能,恕我直言,我认为FavoriteAd是又一个聚合,它同时引用了User聚合和Ad聚合。这样,您就不会因为偏爱行为而负担UserAd的概念。

每次将这些聚合加载到内存中时,也不需要这些聚合来加载此附加数据。例如,如果要加载Ad对象以编辑其内容,则默认情况下不希望将收藏夹集合加载到内存中。

就读取模型而言,这些聚合结构无关紧要。聚合仅处理域的写入。您可以在 read 端随意以多种形式重新连接数据。您可以让订阅者仅监听Favorited事件(在处理Favorite命令之后引发)并构建包含来自User和{{1}的数据的复合数据结构}聚合。

答案 1 :(得分:0)

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

如果仔细查看您的问题,您会发现您已经假设聚合可以“看到”用户与UI交互时所做的一切。不必是这样。

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

在此示例中,“收藏夹”广告命令位于何处都没有关系。它可以是用户汇总的,也可以是用于处理收藏夹概念的特定汇总的。该命令只需要保存用户和他们喜欢的广告的ID。

您可能需要处理删除用户或广告后发生的情况,但这只是事件处理经理监听适当的事件并发出补偿命令的情况。

通过这种方式,您无需加载500万个广告。这是读取模型和UI的工作,而不是域的工作。

只是一个想法。

相关问题