如何正确地持久化和呈现来自多个聚合的信息?

How to correctly persist and present information from multiple aggregates?

我正在创建一个销售平台。核心聚合称为公告,它包含对其他聚合的引用,例如类别、用户等。我正在使用 CQRS 方法作为存储的事件源解决方案。

出于性能原因,我决定将有关关联对象(类别、用户)的一些重要详细信息连同它们的 ID 一起存储在公告聚合中。我背后的原因是,在过滤公告时,我想尽可能地简化对这些信息的访问(减少数据库连接的数量,允许花哨的查询语法)。这是可能的,因为我在命令中包含了所有必需的信息,这会创建一个公告。公告的详细视图的生成基于聚合中嵌入的信息。虽然一开始觉得挺有道理的,现在想起来了。

让我想到的考虑是:

以下步骤是否是所描述问题的有效解决方案?

  1. 从公告聚合中删除重复信息;
  2. 使用域事件通知其他聚合有关创建公告;
  3. 让其他聚合发布适当的事件以响应AnnouncementCreated事件;这些事件可能包含有关关联对象的附加信息;
  4. 引入多流投影,它将根据来自多个聚合的事件进行自我更新并生成公告的完整视图;

一般来说,将数据包含在特定聚合中的唯一原因是该数据是否会影响命令验证,或者是否存在其他一些一致性需求。如果有关类别或用户的信息因任何原因都不符合条件,则将其从公告汇总中删除很有意义。

我可能会考虑对“分类和关联公告”聚合进行建模,该聚合由来自 announcement/category/user 聚合的域事件提供。这可以通过事件存储的多流投影来实现,但我认为将细节分开是有用的,因为还有其他方法可以将来自多个聚合的域事件作为不同聚合的命令提供(任何事件中隐含的命令是“将此事件纳入您的世界观”)。

永远不要通过考虑如何读取数据来设计聚合。这与 CQRS 的目的背道而驰。聚合是关于命令和业务规则而不是查询。使用事件从多个聚合中收集数据,然后在不影响聚合的情况下根据需要投影数据。这个概念叫做“投影”。