CQRS:根据需求建立阅读模型?

时间:2012-08-31 12:20:44

标签: design-patterns architecture cqrs

据我所知,CQRS主张将阅读模型与领域模型分开,并为每个必要的领域模型投影设置特定的阅读模型。

从使用角度来看,读取模型的存储和检索方式应该是透明的 - 您可以发出查询并获取读取模型,而无需关心它是如何制作的。

许多示例和文章使用单独的表来存储读取模型,并通过响应域模型更改来重新生成它们。

由于以下原因,我不太喜欢这种做法:

  • 并非经常需要所有可能的阅读模型;
  • 需求更改可能会使现有的读取模型无效,因此需要重新生成所有这些模型;
  • 如果由于某种原因,read model包含无法在生成时存储但需要计算的属性,则必须使用存储过程/函数/视图;
  • 由于在域模型更改上使用应用程序级缓存时,读取模型与域模型是分开的,因此需要通知所有应用程序需要从缓存中逐出旧的读取模型;
  • 有时完全非常规化复杂对象图是不可能也不可取的,因此您需要具有与特定域实体版本一致的读取模型,即它们需要在同一事务中生成;
  • 某些域实体具有经常更改的属性,但需要包含在每个读取模型中。

基于此,我正在考虑使用查询服务:

  • 对于需要经常生成的读取模型和/或域实体的简单投影:不要存储它们,而是通过查询数据库中的域模型实体通过ORM生成它们;
  • 对于不需要经常生成并且复杂的域实体投影的读取模型生成它们并存储在数据库表中。

另外我看到有人建议将阅读模型存储为blob。将读取模型存储为blob的问题在于,如果您需要搜索它们,则需要提取索引属性,如果需要全文搜索,甚至必须以全文可以理解的格式存储它们工具。

正如您所看到的,我基本上希望只有查询执行后才能读取存在的模型,而不是基于域更改事件生成的模型。这个解决方案对CQRS是否可以接受?我正在研究CQRS的原因是通过将可缓存的视图模型与用户操作处理分离来改进应用程序体系结构,在用户操作之后使用支持AJAX的Web应用程序进行异步更新,并通过将业务逻辑全部放在一起来减少初级开发人员生成不可维护代码的空间对我来说甚至非忠实地实施CQRS似乎是向正确的方向迈出的一步。

1 个答案:

答案 0 :(得分:11)

CQRS不要求读取模型存储在单独的表中(如果使用文档数据库,则存储在文档中),尽管这通常是一种很好的方法,并且与事件源相结合可以很好地工作。例如,数据库视图或ORM查询可以支持读取模型

将CQRS引入遗留系统的某些部分时,这可能是一种很好的方法。

之前已经建议过你建议的方法,例如参见this post by Ayende;我认为它被称为“瘦读模型”或类似。我会说去吧。

您可能有兴趣阅读