如何建模域模型 - 聚合根
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_until
、description
、is_active
等
收藏广告的概念链接了 User
和 Ad
聚合。您的问题似乎集中在应该保留这种联系的地方。它应该在 User
聚合中(Ads
的列表),还是 Ad
应该嵌入 User
object 的 collection在里面?
虽然两者都是可能的,恕我直言,我认为 FavoriteAd
是另一个聚合,它包含对 User
聚合和 Ad
聚合的引用。这样,您就不会因为偏爱行为而给 User
或 Ad
的概念带来负担。
这些聚合也不需要在每次加载到内存时都加载这些额外数据。例如,如果您正在加载 Ad
object 来编辑其内容,您不希望默认情况下将收藏夹 collection 加载到内存中。
就读取模型而言,这些聚合结构并不重要。聚合仅处理域的 write 端。您可以在 read 端以多种形式自由地以任何方式重新连接数据。您可以让订阅者只收听 Favorited
事件(在处理 Favorite
命令后引发)并构建包含来自 User
和 [=11= 的数据的复合数据结构]聚合。
我非常喜欢 Subhash Bhushan 给出的答案,我想添加另一种方法供您考虑。
如果您仔细查看您的问题,您会发现您假设聚合可以 'see' 用户在与 UI 交互时所做的一切。不必如此。
根据域的要求,您无需在聚合中保存任何广告的列表即可收藏它们。这就是我的意思:
对于此示例,'favourite' 广告命令位于何处并不重要。它可以在用户聚合或特定聚合上,用于处理收藏的概念。该命令只需要保存用户的 ID 和他们喜欢的广告。
您可能需要处理删除用户或广告时发生的情况,但这只是事件流程管理器侦听相应事件并发出补偿命令的情况。
这样您就不需要加载 500 万个广告。这是读取模型和 UI 的工作,而不是域。
只是一个想法。
我在正确设计我正在处理的域时遇到了一些问题。
我的直接用例如下:
用户(约 5000 名用户)可以访问广告列表(约 500 万)
他可以选择 add/remove 其中一些收藏。
他可以决定 show/hide 其中一些。
我有一个命令会改变聚合状态,比如说将收藏夹设置为 TRUE。
在DDD方面,我应该如何设计聚合?
如何设计用户与他喜欢的广告选择之间的关系?
考虑到大量广告,我无法在用户聚合根中复制每个广告。
我可以设计一个包含用户“collection”的 Ads aggregateRoot。
最后,如何 handle/perform readmodels 部分?
提前致谢
干杯
两个概念可以帮助您理解如何对此建模:
1.聚合是事务边界。
聚合是一组关联的 object,它们被视为一个单元。聚合的所有部分一起加载和持久化。
如果您有一个包含 1000 个实体的聚合,那么您必须将它们全部加载到内存中。因此,您最好尽可能使用小聚合体。
2。聚合是不同的概念。
聚合表示域中的一个不同概念。与多个聚合关联的行为(如收藏,在您的情况下)通常是一个聚合本身,具有自己的一组属性、域 objects 和行为。
根据您的示例,User
是一个明确的聚合。
一个Ad
在域中有一个与之相关的独特概念,所以它也是一个集合。可能还有其他实体将嵌入广告中,例如 valid_until
、description
、is_active
等
收藏广告的概念链接了 User
和 Ad
聚合。您的问题似乎集中在应该保留这种联系的地方。它应该在 User
聚合中(Ads
的列表),还是 Ad
应该嵌入 User
object 的 collection在里面?
虽然两者都是可能的,恕我直言,我认为 FavoriteAd
是另一个聚合,它包含对 User
聚合和 Ad
聚合的引用。这样,您就不会因为偏爱行为而给 User
或 Ad
的概念带来负担。
这些聚合也不需要在每次加载到内存时都加载这些额外数据。例如,如果您正在加载 Ad
object 来编辑其内容,您不希望默认情况下将收藏夹 collection 加载到内存中。
就读取模型而言,这些聚合结构并不重要。聚合仅处理域的 write 端。您可以在 read 端以多种形式自由地以任何方式重新连接数据。您可以让订阅者只收听 Favorited
事件(在处理 Favorite
命令后引发)并构建包含来自 User
和 [=11= 的数据的复合数据结构]聚合。
我非常喜欢 Subhash Bhushan 给出的答案,我想添加另一种方法供您考虑。
如果您仔细查看您的问题,您会发现您假设聚合可以 'see' 用户在与 UI 交互时所做的一切。不必如此。
根据域的要求,您无需在聚合中保存任何广告的列表即可收藏它们。这就是我的意思:
对于此示例,'favourite' 广告命令位于何处并不重要。它可以在用户聚合或特定聚合上,用于处理收藏的概念。该命令只需要保存用户的 ID 和他们喜欢的广告。
您可能需要处理删除用户或广告时发生的情况,但这只是事件流程管理器侦听相应事件并发出补偿命令的情况。
这样您就不需要加载 500 万个广告。这是读取模型和 UI 的工作,而不是域。
只是一个想法。