`

API设计:CQRS(命令查询职责分离)

阅读更多

以下内容翻译自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
1
0
分享到:
评论
2 楼 RayChase 2013-06-07  
kyfxbl 写道
这个帖子我要MARK一下

今天不小心看到CQRS的概念,再看你这篇文章是2012年的,目前还没有看到这样的应用。请问四火你见过类似的应用吗?

其实很常见,比如查询对象,就是CRUD不对等的模型,只负责查询数据;相似的,还有专门用来写入对象,都是出于逻辑简化或者性能的原因折衷。
1 楼 kyfxbl 2013-06-06  
这个帖子我要MARK一下

今天不小心看到CQRS的概念,再看你这篇文章是2012年的,目前还没有看到这样的应用。请问四火你见过类似的应用吗?

相关推荐

    CQRSArch:CQRS和MediatR的干净架构

    CQRS(命令查询职责分离)是一种设计模式,它将应用程序的读取和写入操作分离,从而提高系统的性能和可维护性。CQRS的核心理念是将数据的读取模型(Query)与更新模型(Command)独立开来,每个模型都可以有自己的...

    CQRS.Sample:CQRS 示例

    CQRS(Command Query Responsibility Segregation,命令查询职责分离)是一种软件设计模式,它将应用程序的读写操作分离,使得系统可以分别对查询和命令进行优化。CQRS模式源自Erich Gamma、Richard Helm、Ralph ...

    CQRS_Study:CQRS研究项目

    **CQRS(命令查询职责分离)**是一种设计模式,它将应用程序的读写操作分离,以提高系统的可扩展性和性能。在CQRS架构中,系统分为两个独立的部分:查询(Query)负责数据读取,而命令(Command)处理数据修改。这种...

    WebAPI-CQRS-MediatR-Basics

    WebAPI-CQRS-MediatR-Basics 是一个项目,它主要展示了如何在C#开发的Web API中应用CQRS(命令查询职责分离)和MediatR库的基本概念。CQRS是一种设计模式,它将应用程序的读取和写入操作分离,以提高系统的可读性、...

    微服务设计模式:构建高效微服务架构的关键技术解析

    接着,文章详细解释了十多种关键的微服务设计模式,如按业务能力和子域分解、扼杀者模式、API网关模式、聚合器模式、每个服务一个数据库、命令查询职责分离(CQRS)、 Saga模式、日志聚合、性能指标、分布式跟踪、...

    NETCoreMicroservices:具有CQRS模式的微服务

    CQRS(命令查询职责分离)模式是微服务架构中的一种设计模式,它将数据的读取操作与更新操作分开,从而提高了系统的复杂性和性能。 在.NET Core中实现CQRS模式,首先需要理解其基本概念。CQRS的核心思想是将一个...

    elixir-cqrs-es:通过http工作

    【描述】:“CQRS(命令查询职责分离)和ES(事件溯源)是两种先进的软件设计模式,常用于构建可扩展和高可维护性的应用程序。在Elixir编程语言中,我们可以利用其强大的并发性和OTP(开放电信平台)框架来实现CQRS...

    User.API:集成网关,身份认证,令牌授权,微服务,.netcore等的基于CQRS的微服务开发框架示例

    【User.API】是一个基于CQRS(命令查询职责分离)原则设计的微服务开发框架,它集成了多种关键组件和技术,以实现高效、可扩展且安全的API服务。这个框架主要关注用户管理,提供了身份验证和令牌授权功能,适用于...

    axon 电子文档 java cqrs

    Axon框架是一种轻量级的Java框架,其核心设计思想是基于领域驱动设计(Domain-Driven Design,DDD)的命令查询职责分离(Command Query Responsibility Segregation,CQRS)模式。CQRS模式将系统的读取和写入操作...

    Distributed-Architecture-BoilerPlate:使用CQRS,RabbitMQ,MassTransit和微服务的样板应用程序

    "Distributed-Architecture-BoilerPlate" 是一个使用CQRS(命令查询职责分离),RabbitMQ,MassTransit以及微服务概念的样例应用,旨在帮助开发者快速理解和实现分布式系统的各种组件。 **CQRS(命令查询职责分离)...

    ThaGet.Cqrs:CQR模板的项目结构

    ThaGet.Cqrs 是一个基于 C# 编程语言实现的CQRS(命令查询职责分离)模式的项目模板。CQRS 是一种软件设计模式,它将应用程序的读写操作分离,以提高系统的可扩展性和性能。在ThaGet.Cqrs 中,我们可以看到典型的...

    kekkonen:用于Clojure的远程(CQRS)API库

    kekkonen是一个专为Clojure设计的库,它支持构建远程API服务,并且基于命令查询职责分离(CQRS)模式。CQRS是一种架构模式,它将应用程序的读取和写入操作分离,以提高系统性能和可扩展性。在CQRS中,读模型和写模型...

    cqalendars:使用 CQRS 样式用 Ruby 编写的示例日历应用程序

    cqalendars 是一个基于 Ruby 实现的示例应用程序,它采用了 CQRS(Command Query Responsibility Segregation,命令查询职责分离)设计模式。CQRS 是一种架构模式,旨在将系统的读写操作分离,从而提高系统的可扩展...

    Jason:Jason 是一个基础架构框架,可以轻松地将 CQRS 的“命令”部分置于 WCF 和 WebAPI 之上

    命令查询职责分离)设计的基础架构框架,它的主要目标是简化在WCF(Windows Communication Foundation)和WebAPI(ASP.NET Web API)上实现CQRS模式的“命令”部分。CQRS是一种软件设计模式,它将系统中的读取和写入...

    Axon4.4 文档中文翻译

    Axon4.4 是一款专为构建基于领域驱动设计(DDD)、命令查询责任分离(CQRS)和事件驱动架构(EDA)的应用程序而设计的框架。它提供了核心框架(Axon Framework)和Axon Server,两者共同帮助开发者创建可扩展、高可...

    ABP框架集成授权网关、含公共接口,适用于中型项目

    1. **ABP框架**:ABP框架的核心特性包括模块化、层分离、依赖注入、领域驱动设计(DDD)、事件溯源和CQRS(命令查询职责分离)。它基于ASP.NET Core,支持Web API和MVC应用,提供了丰富的基础设施和工具,帮助开发者...

    DTHServices:Dth服务API

    在本文中,我们将深入探讨如何利用.NET 5框架,结合CQRS(命令查询职责分离)模式和中介者模式来构建高效且可扩展的多媒体广告服务系统。 CQRS(命令查询职责分离)是一种架构模式,它将读取和写入操作分离到不同的...

    微服务中的领域驱动设计共21页.pdf.zip

    - 数据一致性:事件溯源和CQRS(命令查询职责分离)策略在微服务中用于处理跨服务的数据一致性问题。 - API Gateway:作为微服务的统一入口,负责路由、聚合、权限控制等功能,简化客户端接口。 4. 实践技巧: -...

    pluggable-cqrs-mechanism

    CQRS(Command Query Responsibility Segregation,命令查询职责分离)是一种设计模式,它将一个应用程序的读写操作分离,分别用独立的数据模型和存储来处理。这种模式在大型分布式系统中尤其常见,因为它能够提高...

    MediumApi:中型简单站点实现,带来了CQRS,Mediator和微服务模式

    MediumApi 是一个基于 C# 实现的简单站点,它采用了现代软件设计模式,如CQRS(命令查询职责分离)和Mediator(中介者)模式,以及微服务架构思想,来构建可扩展、可维护的系统。本文将深入探讨这些关键知识点。 **...

Global site tag (gtag.js) - Google Analytics