本文主要是介绍DDD里面的CQRS到底是什么?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
开篇
随着业务不断发展,软件系统的架构也越来越复杂,但无论多复杂的业务最终在系统中实现的时候,无非是读写操作。用户根据业务规则写入商业数据,再根据查询规则获取想要的结果。通常而言我们会讲这些读写的数据放到一个数据库中保存,通过一套模型对其进行读写操作。而在大型系统中往往查询操作远远多于写入操作,于是就有了读写分离的思想,将读操作和写操作的模型分开定义并且提供不同的通道供用户使用。CQRS(Command-Query Responsibility Segregation) 就是基于这一思想提供的一种模式读写分离的模式,今天就围绕着它给大家讲述以下内容:
-
CQRS的演变和架构
-
Event Sourcing 原理与应用
-
Event Sourcing 与CQRS的完美结合
-
CQRS的例子
CQRS的演变和架构
CQRS(Command-Query Responsibility Segregation) 是一种读写分离的模式,从字面意思上理解Command是命令的意思,其代表写入操作;Query是查询的意思,代表的查询操作,这种模式的主要思想是将数据的写入操作和查询操作分开。
它源于Bertrand Mayer设计的命令查询分离(CQS)原理。CQS声明一个类只能有两种方法:改变状态并返回void的方法和返回状态的方法。而Greg Young 是负责命名这种模式为CQRS 并推广它的人。
首先来看看在没有CQRS之前是如何处理系统中的修改和查询的吧,如图1所示:
图1 传统的系统请求
传统的系统请求从最左边的Client开始,沿着红线往右通过Application Service对系统进行请求。这里Application Service 可以理解为系统的门面,或者是Controller层负责接收客户端的请求,此时请求的内容比较简单基本和数据库中的信息一致,因此这里使用DTO(Data Transfer Object)直接请求。DTO经过Domain Model 以后直接到达Database,从而沿着蓝色的线条返回给Client端。传统的请求方式部分读操作和写操作,都使用同样的数据模型和一套Domain Model以及相同的数据库。
从传统操作来看Client的请求在经过Application Service,用户意图全部被分解为CRUD操作,但是在Domain Model中是无法体现的。为保证DTO的完整性和一致性,与操作无关的信息会被纳入DTO,查询操作和创建操作都共用一个DTO,而领域模型的业务流程被弱化。为了适应同时适应查询和创建操作,DTO被设计的面面俱到,也就显得臃肿。从而在传输中存在不必要的字段传递。
而且一次操作,在DTO与领域对象间进行多次转换,增加了系统复杂度。还有,读写操作将围绕同一数据模型展开,对于读多写少的系统而言效率并不是最高的,特别在读操作为主的高并发系统中缺点就尤为突出。
正因为传统系统架构存在上面这些问题,因此CQRS根据读写职责的不同,把领域模型切分为Command端与Query端两个部分,如图2所示,红色线部分就是Command端,其对应的是Domain Model 对其发送Command 操作的指令往数据写入状态信息。
Query端作为查询操作,由蓝色的线表示,通过Query Model向数据库获取信息,通过黑色向左的先返回结果给Client。Command端与Query端都通过Application Service 进入系统,共享同一个数据库,但Command端只写入状态,Query端只读取状态。
图2 CQRS 分为Command 端和 Query端
目前而言已经将读写操作分开了,由于两个操作依旧共用一个数据库,为了提高读写效率数据库的分离就成为必然的选择。如图3所示,于是将原来的Database,分离为Writer Database 和Reader Database分别用于写操作和读操作。为了保证读写操作的数据一致性,需要在两个数据库之间进行数据同步。<
这篇关于DDD里面的CQRS到底是什么?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!