我正在学习什么是CQRS模式,并且知道还有CQS模式。
当我尝试搜索时,我发现了很多关于CQRS的图表和信息,但没有发现太多有关CQS的信息。
CQRS模式的关键点
在CQRS中,有一个完全独立的模型(命令模型)和一个模型(查询模型)编写。
CQS与CQRS有何不同?
Answers:
CQS(命令查询分离)和CQRS(命令查询责任分离)非常相关。您可以认为CQS处于类或组件级别,而CQRS则更多地处于受限上下文级别。
我倾向于认为CQS在微观层面,而CQRS在宏观层面。
CQS规定了用于查询模型或向模型写入的单独方法:查询不改变状态,而命令改变状态但不具有返回值。它是由Bertrand Meyer设计的,是他在Eiffel编程语言方面的开创性工作的一部分。
CQRS规定了类似的方法,只是它更多地是通过系统的路径。查询请求采用与命令不同的路径。该查询将返回数据,而不会更改底层系统。该命令更改系统,但不返回数据。
格雷格·杨(Greg Young)对几年前的CQRS进行了非常详尽的撰写,并探讨了CQRS是CQS的演变。该文档几年前向我介绍了CQRS,我发现它仍然是非常有用的参考文档。
这是一个古老的问题,但我要回答一下。我不经常在StackOverflow上回答问题,因此,如果我在社区范围之外做一些事情,例如链接到事物,写长答案等,请原谅我。
CQRS和CQS之间有很多区别,但是CQRS在其定义内使用CQS!让我们先定义两者,然后讨论差异。
CQS根据消息的返回值定义了两种类型的消息:没有返回值(无效)表示这是一条命令;返回值(非void)指定此方法为查询。
命令更改状态。查询不。
现在是CQRS,它使用与CQS相同的命令和查询定义。CQRS所说的是我们不希望使用Command和Query方法的对象。相反,我们需要两个对象:一个包含所有命令,一个包含所有查询。
总的来说,这个想法很简单。这一切后,这样做,事情变得有趣。在线上有很多演讲,我讨论了一些相关的属性(很抱歉,此处无法键入!)。
最大的区别是CQRS使用单独的数据存储来存储命令和查询。查询存储可以使用诸如文档数据库之类的不同技术,也可以只是同一数据库中的非规范化架构,这使得查询数据更加容易。
数据库之间的数据通常使用服务总线之类的方法异步复制。因此,查询存储中的数据最终是一致的(在某个时间点将在那里)。应用程序需要考虑到这一点。虽然可以在两个存储中使用相同的事务(相同的数据库或两阶段提交)进行写入,但是出于可伸缩性的原因,通常不建议这样做。
CQS体系结构从相同的数据存储/表读取和写入。
阅读发明家Greg Young的答案
我认为,像“依赖注入”一样,这些概念是如此简单且被认为是理所当然的,以至于它们拥有奇特的名称这一事实似乎使人们认为它们比实际的要重要得多,特别是因为CQRS通常与事件源一起被引用。
CQS是将读取方法更改为更改状态的方法的分离;请勿同时使用两种方法。这是微观层面。
CQRS将这一概念扩展到了机器-机器API的更高层次,消息模型和处理路径分离。
因此,CQRS是您应用于API或Facade中的代码的原则。
我发现CQRS在SOLID中本质上是非常强大的S,将这种分离深深地吸引到开发人员的头脑中,以产生更多可维护的代码。
我认为Web应用程序不适合CQRS,因为通过表示传递进行状态改变意味着命令和查询是同一请求响应的两个方面。表示形式是命令,响应是查询。
例如,您发送一个订单并接收所有订单的视图。
想象一下,网站的代码是否被分解为命令方和查询方。路由动作处理代码将需要落入这些方面之一,但两者都需要。
设想更严格的隔离,如果将代码移到两个不同的可编译代码库中,则该网站将接受某种形式的POST,但是用户必须浏览到另一个网站URL才能查看此操作的影响。这显然是疯狂的。一种解决方法是始终重定向,尽管这并不是真正的RESTful,因为理想的REST应用程序是下一个表示形式包含超文本来驱动下一个状态转换的地方,依此类推。
假定网站是人与机器(或机器与机器)之间的REST API,尽管其他类型的HTTP消息传递API可能非常适合CQRS,但网站也包括REST API。
尽管动作处理程序位于该边界之外,但网站范围内的服务或外观显然可以与CQRS很好地配合使用。
我发现人们经常说他们有CQS时就会练习CQRS。