Golang领域模型-CQRS

奔奔奔跑 · · 126 次点击 · · 开始浏览    

前言: CQRS一词随着DDD一同被大众所熟悉,但是你有没有想过CQRS一词其实并非DDD独有,非DDD设计项目也能用,或许你正在用,但你不知道而已。本文介绍了一下CQRS是什么,在DDD中的作用,以及在项目中使用CQRS的好处。

一、什么是CQRS?

先从概念开始,CQRSCommand Query Responsibility Segregation的缩写,译成中文就是“命令与查询职责分离”。

顾名思义在我们写CRUD代码的时候,其实是有可分为两类操作,一类是query(查询),一类是command(增删改)。

记住以下几点:

  • 这个从分离关注点的角度来看,一个对数据无修改,一个则对数据有修改,二者的关注点是不同的,可以将其分离。
  • 二者从代码结构上看,能够将聚合根的臃肿程度降低。
  • 从性能上看,可以分别最大化读写的性能。

二、要不要用CQRS?

2.1 举例说明分层实践中的常规操作

不管你是否在进行DDD项目,其实你或多或少已经在接触或者使用CQRS了。

常规操作.png

上图的操作方式是不是很熟悉,相当常规的开发操作,Model包里面建个model,然后在DAO层或者说Repository层中对改model进行增删改查操作。

一般而言这种操作是没有问题,或者说大家都是这么干的。那么我举个栗子,看看大家是否又能找到这种开发中熟悉的感觉!

例如:电商项目,商品(Goods)服务中的订单操作,开始只需要实现两个方法:

商品Repository
type GoodsRepository interface {
    Save(ctx context.Context, order *model.Goods) error
    GetByID(ctx context.Context, id int) (order *model.Goods, error)
}

好了,开启迭代模式:

  1. 需要展示商品详情,但是所需字段比model.Goods中的字段要少。
  2. 需要展示Goods列表,列表中所需要的信息比商品详情中更少。
  3. 根据时间、商品种类,标签、售价、利润···等维度对商品进行筛选展示。
  4. 展示商品的供应商,而供应商管理属于另一个业务服务
  5. 。。。
    。。。

当你迭代完成,回头看你的代码,有没有发现:

  1. 你的GoodsRepository里面居然全是查询的操作代码。
  2. 为了应对不同的业务数据要求,需要将model.Goods中的数据进行裁剪与转换,这部分繁多的代码是放在Service中,还是在Repository中?是不是犯迷糊了,想想咱们DDD系列的第二篇文章《六边形架构》,或许你会有所收获。

CQRS通过单独读模型解决上面的问题

2.2 CQRS的不同模式

CQRS中的读写分离可以分为两个层次:

  1. 代码层面的读写分离。


    相同存储-读写模型分离.png

该模型的数据存在相同的DateBase中,通过在业务代码中使用不同的分离后的读写模型,减少了繁多且又没法避免的数据转换操作。

  1. 存储层面的读写分离。
    存储分离-模型分离.png

    CQRS模型分离的更为彻底,不仅仅分离了读写模型,底层数据存储也一并分离了。读写操作分别写入不容的存储中,然后通过消息机制进行数据同步。

总结:

  1. 并不是项目中所有的model都需要进行CQRS改造,并不是所有的CQRS一定要将读写数据进行分离。
  2. 代码层面进行的CQRS有利于分离关注点,让代码层次结构更清晰,容易维护。
  3. 存储层次的CQRS应用于高性能查询场景,经常见于大型项目中MySQL存储商品,然后用ES查询商品等需要快速响应的场景。

三、Freedom中怎么使用CQRS?

目录

  • golang领域模型-开篇
  • golang领域模型-六边形架构
  • golang领域模型-实体
  • golang领域模型-资源库
  • golang领域模型-依赖倒置
  • golang领域模型-聚合根
  • golang领域模型-CQRS
  • golang领域模型-领域事件

项目代码 https://github.com/8treenet/freedom/tree/master/example/fshop

PS:关注公众号《从菜鸟到大佬》,发送消息“加群”或“领域模型”,加入DDD交流群,一起切磋DDD与代码的艺术!


有疑问加站长微信联系

本文来自:简书

感谢作者:奔奔奔跑

查看原文:Golang领域模型-CQRS

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:812540095

126 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传