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

Aru*_*nas 6 architecture design-patterns cqrs

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

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

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

我不喜欢这种方法,原因如下:

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

基于此,我想有查询服务应该:

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

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

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

Mar*_*ijn 11

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

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

之前已经建议过你在这里建议的方法,例如参见Ayende的这篇文章 ; 我认为它被称为"瘦读模型"或类似.我会说去吧.

你可能有兴趣阅读