以下内容翻译自CQRS by Martin Fowler,有一些修改:
CQRS(Command Query Responsibility Segregation)指的是命令查询职责分离。这是一种我从Greg Young处听到的模式描述。它的核心思想很简单,就是你在更新和读取操作时使用不同的模型,这样的话,会给整个系统的设计带来深远的变革。
人们和信息系统交互的主流行为就是对数据仓库CRUD的使用,我们构思一个可以供创建、读取、更新和删除的数据模型。简单来说,我们的接口提供出来的目的就是供存储和获取数据之用的。
现在我们要脱离这样一种模型,看看另一种存储数据的方式,可能是把很多数据打包成一个数据对象,或者把一些数据按照某种格式压缩成一种新的格式存储起来。在数据更新这块,我们可以找到一些校验方式来对上述要存储的数据进行校验,甚至可以推断出我们提供的数据和现有的存储数据有什么不同。
传统方式:
这样一来,我们可以开始用多种视角来看待数据的呈现了。当用户和数据交互的时候,他们使用的是不同种的数据呈现方式。开发者通常会构建他们自己觉得正确的核心属性的概念模型,如果你在使用领域模型,那么这就是一种概念上的领域模型的表达,你当然也可以对数据的存储定义这样的一个概念模型。
今天提到的方式:
CQRS则做了改变,它将这个模型拆分成命令和展示两部分,分别叫做Command和Query。这样对于很多问题,特别是复杂的领域,相对于对命令和查询使用同一概念模型,复杂性降低。
把模型拆开来,这意味着可以用不同的逻辑进程、不同的硬件来做这两部分事情了。一个WEB上的例子,用户查看页面的时候使用查询模型;而如果要改变数据,这种改变会解析成若干命令模型来执行操作,操作完毕后通知状态的更新。
这里有一些变数需要考虑,内存中的两种模型可以来自同一个数据库,但也可以来自不同的数据库。比如可以让数据的查询来自实时的ReportingDatabase(一种只提供读取服务的数据库概念,Bliki上尽是概念,有的东西还真不怎么样,呵呵,译注),这样的话就需要一种存在于不同数据库之间的数据通信机制。
两种模型,那么原本相同的对象就需要不同的方法来操纵和查询了,就像关系数据库中的不同视图。不过我一听说了CQRS的介绍,这两种模型在脑海里一下子清晰起来。
我们把一个通过CRUD来交互的模型,挪到基于事件的UI层,对于基于事件溯源的场景我们使用命令模型。如何保持两种模型的一致性呢?这里需要考虑事件层面的一致性。很多情况下只有你在更新数据前才需要执行业务逻辑,所以使用EagerReadDerivation(这个我不知道怎么翻译,建议大家打开链接看一看,读请求可以直接从ReportingDatabase中获取数据,而不经过逻辑处理,这个思路是有些奇特,见下面的图,译注)来简化你的查询模型是有很大意义的。
像很多模式一样,CQRS只在某些场合适用,它带来了一种思维上的跳跃,如果不能从中获益,就不要考虑它。尤其值得一提的是,CQRS只在某些特殊系统的某部分中使用(如面向领域设计中提到的Bounded Context)。
目前为止我只看到只有两个方面在此获益。一个是针对非常复杂的场景,可以用CQRS简化问题。通常我尽量不这么做,因为在命令和查询两部分重叠较多,有足够多的方法属性可以重用;另一个情况是对于高性能的应用,如果读写比例太悬殊,
CQRS可以让你分开考虑横向扩展,即便是传统方式,你也得对读写考虑不同的优化策略。一个例子是使用不同的数据库访问技术来处理查询和更新。
如果你的场景不适合使用CQRS,但是你又面对查询的复杂性和性能问题,你仍然可以试试这个ReportingDatabase,因为这样你仍然可以使用你原来的系统,只是对于一些特殊要求的查询,切换到这个ReportingDatabase上去(我通读了一下关于这个东西的文章,也没有见到它有特别优秀的地方,再者,对于这样一些变态场景,更可能会考虑的是一些成熟的读写库分离技术,译注)。
我们目前还没有看到很多使用CQRS的地方,我们理解大家对它赞成和反对的理由,CQRS依然是我工具箱中必不可少的一把利器,虽然我不经常使用它。
文章系本人原创,转载请注明出处和作者
- 大小: 125.8 KB
- 大小: 144.7 KB
- 大小: 133.9 KB
分享到:
相关推荐
一个基于 DDD 领域驱动设计 CQRS 命令查询职责分离 的 .net core 框架,完全开源。ASP.NET Core 2.1 应用, 包含 DDD、CQRS 和事件回溯。
本文介绍了命令查询职责分离模式(CommandQueryResponsibilitySegregation,CQRS),该模式从业务上分离修改(Command,增,删,改,会对系统状态进行修改)和查询(Query,查,不会对系统状态进行修改)的行为。...
满足命令查询职责隔离(CQRS)模式实现的两个应用程序。 简单的CQRS CQRS代表命令查询责任隔离。 它是一种设计模式,用于强制将修改应用程序状态的操作与使应用程序状态保持完整的操作分开。 引用:“对象被分为两...
CQRS:通用命令CQRS [命令和查询责任隔离]
CQRS命令API 使用Web API从CQRS实施命令的示例 依存关系 .NET 5 调解员 内容描述 仅执行命令
ThaGet.Cqrs.Abstractions:cqrs模板的抽象
CQRS和DDD架构模式抽象的这项工作提出了CQRS(命令和查询责任隔离)和DDD(域驱动设计)体系结构模式的实际应用,其中包括: 领域模型和有界上下文定义技术代码和业务逻辑之间的清晰分离指令端休息API 查询侧边api ...
简单的 CQRS 示例 .Net 中命令和查询职责分离的简单示例 博客文章
cqrs 表示命令和查询职责分离。 它来自遥远的地方,所以将是一个更好的地方来了解更多。安装npm install --save cqrs.jsbower install --save cqrs.js require ( [ 'cqrsjs' , ...例子建立在 restify 和 socket.io ...
CQRS读写分离模式的例子
CQRS.Sample详细介绍:
CQRS微服务模板 这是什么? 使用dotnet new时,此项目充当dotnet cli...运行cqrs-ms模板的卸载命令 升级中 升级时,最佳实践是先卸载模板,然后在拉到最新版本后重新安装 用法 参数 描述 项目名-P 模板的标准项目
CQRS CQRS研讨会
CQRSArch CQRS和MediatR的干净架构干净的建筑CQRS 中介列表分页流利的API
完整的解决方案引导程序-自下而上: CQRS和域驱动开发堆栈-发送和处理命令,查询,事件(使用库), 消息传递基础结构-基于内部和外部与和CRUD应用程序服务, (还支持和 ) WebApi REST控制器, 通过自动命名约定...
简单的说,就是一个系统,从架构上把它拆分为两部分:命令处理(写请求)+查询处理(读请求)。然后读写两边可以用不同的架构实现,以实现CQ两端(即Command Side,简称C端;Query Side,简称Q端)的分别优化。CQRS...
JdonFramework应用案例之一: JdonFrameworkTest CQRS+ES
CQRS +用于PHP 7+的事件源库 这是一个非性的 +事件源库,可帮助构建复杂的DDD Web应用程序。 域代码中对库的最小依赖 仅需要实现3个接口 没有继承! 您的域代码保持整洁,并且与基础架构/框架无关。 \Dudulina\...
CQRS深入了解命令 CQRS查询和实现 CQRS共识和一致性 CQRS分布式混沌,CAP定理 :floppy_disk: 如何使用? 您需要以下一些工具: 码头工人 Visual Studio 2019 .Net Core 3.0 :bullseye: 清洁建筑 这是此...