架构设计之解析CQRS架构模式!

CQS思想

CQS:命令和查询分离:Command and Query Segregation

其核心思想是在任何一个对象的方法可以划分为两类:

  • 查询:获取数据,返回查询数据,但不改变数据状态。
  • 命令:改变数据状态,不返回任何数据。

CQRS模式的核心设计理念来自于一条设计原则,即单一职责原则

  • 所谓单一职责原则,指的是一个技术组件只应该负责具体一项职责。

    • 而不应该有多个导致该组件发生状态变化的操作。

基于CQS的思想,任何一个方法都可以拆分为命令和查询两部分,如下:

 

arduino

代码解读

复制代码

private int data = 0; private int update(int value) {   data += value;   return data; }

上述方法既改变了数据,又返回了数据状态。

如果按照CQS的思想,则该方法可以拆成CommandQuery两部分,如下:

 

csharp

代码解读

复制代码

private void update(int value) {   data += value; } private int query() {   return data; }

对于命令侧是否返回数据实际业务诉求中并不一定能够完全统一。

比如:

  • 某些业务场景下可能会有返回业务主键的诉求,比如下单操作返回订单号。

基本原则

CQS的主要原则是:

  • 一个方法要么是命令,要么是查询,但不能两者兼有。
  • 这种分离有助于提高代码的可读性和维护性,因为它明确了方法的用途。

CQRS架构

 
 

代码解读

复制代码

Command and Query Responsibility Segregation
  • 即命令查询职责分离,是一种将命令和查询的责任明确分离的架构模式。
  • 这种模式进一步扩展了CQS的思想,适用于更大规模的系统架构。

架构思想:

CQRS将系统的读操作和写操作分离到不同的模型中:

  • 命令模型(Command Model):

    • 处理数据的写操作(创建、更新、删除)。
  • 查询模型(Query Model):

    • 处理数据的读操作(查询)。

这种分离可以通过不同的数据模型、数据库甚至服务来实现,从而优化读写性能和可伸缩性。

CQRS 模式的应用非常简单,如下图所示:

假设服务为 UserService,在非CQRS模式下同时包含了查询和更新服务接口。

 

java

代码解读

复制代码

public class UserService {   // 根据id查询用户   UserId getUserId(int userId);   // 更新用户   void updateUser(User user); }

应用CQRS模式之后的UserService被拆分成了两个接口,分别承担查询和写职责。

 

java

代码解读

复制代码

/**   命令服务 */ public class UserCommandService {   void updateUser(UserCommand command); } /**   查询服务 */ public class UserQueryService{   User getUserById(int userId); }

最终一致性

采用CQRS后,查询和命令两侧通常会采用独立的数据模型

  • 采用CQRS模式并没有强制要求必须要进行数据模型的分离。

在这种架构模式下,命令侧的数据变化后及时同步(事件、消息队列)到查询侧,两侧数据并非实时。

  • 在一定的延时后两侧数据最终达成一致。

最后总结

CQRS的使用者可以根据实际情况,将读写分离开单独部署,然后引入领域事件,使用消息队列做通信。

  • 但是这些都是基于不同业务场景的架构选择,而非CQRS本身的要求。
  • 实际上CQRS只是一种非常简单的模式而已,并没有和事件、消息队列这些有强关联。

读写分离部署+消息通信:

  • 会带来额外的系统复杂性和更高的运维成本。

《重构:改善既有代码的设计》的作者也提醒要小心使用CQRS,不推荐将CQRS复杂化处理。

参考资料:

  • CQRS 模式
  • 在微服务中应用简化后的 CQRS 和 DDD 模式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值