# 淺談CQRS

CQRS (**Command Query Responsibility Segregation**) 命令查詢職責分離模式，在談論這個之前必須要先談論OO(Object-Oriented)裡面的CQS(Command Query Separation)因為兩者的概念一樣，只是應用層級不太一樣。

### CQS

CQS 使用於寫程式層級，將Object主要分為兩種動作command、query:

* Command:  指的是改變物件狀態的動作，ex: Create, Update, Delete
* Query: 指的是不會改變物件狀態的動作，ex: Read.

舉個例子:

```javascript
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 模式就可以進而提昇效能。如下示意圖。

{% hint style="info" %}
master-slave pattern 指的是主動或者被動的方式將資料同步到其他資料庫&#x20;
{% endhint %}

![](https://853423727-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZBn9owI5fBe0HrECdk%2Fuploads%2FwmA47m4byYKoIrLdqTiU%2Fimage.png?alt=media\&token=3e540cb0-68b2-43f9-9747-759a08bf2e35)

### **參考資料**

\[1] <https://martinfowler.com/bliki/CQRS.html>\
\[2] <https://martinfowler.com/bliki/CommandQuerySeparation.html>
