为什么 CQRS - Why CQRS
CQRS (Command Query Responsibility Segregation) 命令查询职责分离模式,在谈论这个之前必须要先谈论OO(Object-Oriented)里面的CQS(Command Query Separation)因为两者的概念一样,只是应用层级不太一样。
From personal blog
CQS
CQS 使用于写程式层级,将Object主要分为两种动作command、Query:
Command: 指的是改变物件状态的动作,ex: Create, Update, DeleteQuery: 指的是不会改变物件状态的动作,ex: Read.举个例子:
function Array() { this.arr = []}// Insert 属于 "Command" 因为所执行的事情是将element 存入 arr 中,改变了状态Array.prototype.Insert = function (element) { this.arr.push(element)}// Read 属于 "Query" 因为只是读取并未改变Array 整个物件的状态Array.prototype.Read = function (index) { return this.arr[index]}
其中CQS 有一个特性,
会改变状态的方法不会回应物件状态,反之不会改变状态的回应物件状态
。换句话说Command 因为是改变状态的动作,则会不会有Return ; Query 则会有Return。
CQRS
也别于CQS,CQRS 则是将 Command、Query的概念拉到系统层级,以资料库中Create, Read, Update, Delete (CRUD) 四个动作为例,大多时候Read才是大量被使用的。而使用CQRS 就能够轻易的增加Read 用的伺服器,为此增加弹性,并且能够轻易的做出针对性的效能教调。
举个例子:
如果将资料库的存取拆分成Command、Query,资料库的选择上会有一些变化,如Command 换成写入较快的,Query 则换成读取较快的。透过资料库本身的Master-slaves 模式就可以进而提昇效能。如下示意图。
master-slave pattern 指的是主动或者被动的方式将资料同步到其他资料库;
参考资料
[1] https://martinfowler.com/bliki/CQRS.html
[2] https://martinfowler.com/bliki/CommandQuerySeparation.html