我在正确设计正在使用的域时遇到了一些问题。
我的简单用例如下:
该用户(约5000个用户)可以访问广告列表(约500万个)
他可以选择添加/删除其中一些作为收藏夹。
他可以决定显示/隐藏其中一些。
我有一条命令会改变聚合状态,比如说将Favorite设置为TRUE。
就DDD而言,应该如何设计聚合?
如何设计用户与其最喜欢的广告选择之间的关系?
考虑到广告数量众多,我无法在用户聚合根目录内复制每个广告。
我可以设计一个包含用户“集合”的Ads AggregationRoot。
最后,如何处理/执行readmodels部分?
预先感谢
欢呼
答案 0 :(得分:2)
两个概念可以帮助您了解如何对此建模:
1。汇总是交易边界。
集合是关联对象的群集,被视为一个单元。聚合的所有部分均已加载并保持在一起。
如果聚合包含1000个实体,则必须将所有实体加载到内存中。因此,您最好在可能的情况下最好使用较小的聚集体。
2。聚合是不同的概念。
集合表示域中的不同概念。与多个聚合相关联的行为(例如您的收藏夹行为)通常是具有其自身的一组属性,域对象和行为的聚合。
在您的示例中,User
是明确的汇总。
Ad
在域中具有与之相关的独特概念,因此它也是一个聚合。可能还有其他实体会嵌入到广告中,例如valid_until
,description
,is_active
等。
收藏广告的概念将User
和Ad
聚合链接在一起。您的问题似乎集中在应保留此链接的位置。它应该是User
聚合(Ads
的列表),还是应该在Ad
中嵌入User
个对象的集合?
虽然两者都有可能,恕我直言,我认为FavoriteAd
是又一个聚合,它同时引用了User
聚合和Ad
聚合。这样,您就不会因为偏爱行为而负担User
或Ad
的概念。
每次将这些聚合加载到内存中时,也不需要这些聚合来加载此附加数据。例如,如果要加载Ad
对象以编辑其内容,则默认情况下不希望将收藏夹集合加载到内存中。
就读取模型而言,这些聚合结构无关紧要。聚合仅处理域的写入。您可以在 read 端随意以多种形式重新连接数据。您可以让订阅者仅监听Favorited
事件(在处理Favorite
命令之后引发)并构建包含来自User
和{{1}的数据的复合数据结构}聚合。
答案 1 :(得分:0)
我真的很喜欢Subhash Bhushan给出的答案,我想添加另一种方法供您考虑。
如果仔细查看您的问题,您会发现您已经假设聚合可以“看到”用户与UI交互时所做的一切。不必是这样。
根据域的要求,您无需保留汇总中的任何广告的列表即可收藏它们。这就是我的意思:
在此示例中,“收藏夹”广告命令位于何处都没有关系。它可以是用户汇总的,也可以是用于处理收藏夹概念的特定汇总的。该命令只需要保存用户和他们喜欢的广告的ID。
您可能需要处理删除用户或广告后发生的情况,但这只是事件处理经理监听适当的事件并发出补偿命令的情况。
通过这种方式,您无需加载500万个广告。这是读取模型和UI的工作,而不是域的工作。
只是一个想法。