- 作者:老汪软件技巧
- 发表时间:2024-09-28 21:01
- 浏览量:
文章内容收录到个人网站,方便阅读:/
文章内容收录到个人网站,方便阅读:/
文章内容收录到个人网站,方便阅读:/
❝
CQRS叫命令查询职责分离,事实上就是读写分离的意思。
CQRS指的读写分离是指在应用程序内部的代码级别的读写分离。
在本文中,我将对此做出详细解释。
CQS思想
❝
CQS:命令和查询分离:Command and Query Segregation。
其核心思想是在任何一个对象的方法可以划分为两类:
CQRS模式的核心设计理念来自于一条设计原则,即单一职责原则。
基于CQS的思想,任何一个方法都可以拆分为命令和查询两部分,如下:
private int data = 0;
private int update(int value) {
data += value;
return data;
}
❝
上述方法既改变了数据,又返回了数据状态。
如果按照CQS的思想,则该方法可以拆成Command和Query两部分,如下:
private void update(int value) {
data += value;
}
private int query() {
return data;
}
❝
对于命令侧是否返回数据实际业务诉求中并不一定能够完全统一。
比如:
基本原则
❝
CQS的主要原则是:
CQRS架构
❝
Command and Query Responsibility Segregation
架构思想:
❝
CQRS将系统的读操作和写操作分离到不同的模型中:
查询模型(Query Model):
这种分离可以通过不同的数据模型、数据库甚至服务来实现,从而优化读写性能和可伸缩性。
CQRS 模式的应用非常简单,如下图所示:
❝
假设服务为 UserService,在非CQRS模式下同时包含了查询和更新服务接口。
public class UserService {
// 根据id查询用户
UserId getUserId(int userId);
// 更新用户
void updateUser(User user);
}
❝
应用CQRS模式之后的UserService被拆分成了两个接口,分别承担查询和写职责。
/**
命令服务
*/
public class UserCommandService {
void updateUser(UserCommand command);
}
/**
查询服务
*/
public class UserQueryService{
User getUserById(int userId);
}
最终一致性
❝
采用CQRS后,查询和命令两侧通常会采用独立的数据模型。
在这种架构模式下,命令侧的数据变化后及时同步(事件、消息队列)到查询侧,两侧数据并非实时。
最后总结
❝
CQRS的使用者可以根据实际情况,将读写分离开单独部署,然后引入领域事件,使用消息队列做通信。
读写分离部署+消息通信:
《重构:改善既有代码的设计》的作者也提醒要小心使用CQRS,不推荐将CQRS复杂化处理。
参考资料: