CQRS - 允许使用事件和其他信息源构建读取模型的依赖关系

时间:2010-12-13 10:08:24

标签: cqrs

我的问题与CQRS(命令和查询责任隔离)以及构建阅读模型(视图)的机制有关。据我所知,读模型是由事件处理程序构建的。这些处理程序(也称为非规范化程序)接收域事件并使用这些事件来构建不同的数据视图。

特定事件包含有关域模型中所做更改的信息。我认为这些信息在某些情况下不足以构建视图 - 即没有更改的字段,在这种情况下没有更改的实体丢失等。

所以我的问题是:

是否允许负责构建读取模型的非规范化程序不仅访问事件,还允许:

  1. 直接更改了实体 事件?
  2. 更改了聚合根和任何 与此汇总相关的实体?
  3. 从存储库中提取的任何实体?
  4. 任何观点?
  5. 您对事件处理程序(非规范化程序)的允许依赖项有何看法?

    编辑:刚刚在上面的问题中添加了简单的示例:

    假设以下模型:

    AR:ProductOffering  * 名称  *描述  *类别  *价格

    AR:客户  * 名称  *类型  *方法:发出的purchaseProduct(productOffering) ProductPurchasedByCustomer事件

    实体:ProductInstance  *客户  * productOffering

    事件:ProductPurchasedByCustomer  * 顾客ID  * productOfferingId

    view:ProductInventoryView  * 顾客ID  * productOfferingId  * 客户类型  * productOfferingName  * productOfferingCategory  *价格

    如何仅使用ProductPurchasedByCustomer事件构建ProductInventoryView?如何编写denormalizer以查看有关customerType,productOfferingName等的信息? 我应该从不同的视图中查找有关customerType和productOfferingName的其他信息吗?

2 个答案:

答案 0 :(得分:6)

如果事件消费者需要更多信息,那么事件生产者可以提供所需的信息,尽管它没有改变。不应将事件源视为ORM。请注意,关于如何获取信息,事情可能会变得棘手,但不要让事情复杂化(但)。如果事件未提供事件处理程序,则事件处理程序可以使用读取模型的状态(数据)。但这样做需要您知道是否可以使用哪些数据。它需要您将时间与数据相结合。消息/事件很可能无序处理。因此,在事件中提供与事件相关的信息要容易得多。在做任何其他事情之前尝试这样做。不要尝试从特定于您的阅读模型的事件处理程序访问您的域,这只是讨厌的耦合。最后一点,聚合可以从其他聚合中复制数据,以提供事件中所需的数据。请注意,从那时起,您必须开始考虑如何在首先复制数据的聚合中保留新数据。可能会让你更困惑......

答案 1 :(得分:0)

根据我的理解:

  

更改了事件中直接引用的实体?

没有

  

更改了聚合根和与此聚合相关的任何实体?

没有

  

存储库获取的任何实体?

没有

  

与事件

无关的任何报告

没有

  

为在事件中直接引用的实体更改了实体报告

  

更改了聚合根报告以及与事件中引用的聚合相关的任何实体报告


因为denormalizer应该对域存储库一无所知,只更新相关报告。

如果报告看起来不相关但必须更新,那就是代码味道 - 很可能你正在设计你的模型/报告错误。