命令查詢分離的藝術
將副作用管理起來
管理副作用的一個好方法是對命令和查詢分離,並在它們之間建立一個強大的分隔邊界。在良好命令和查詢分離的情況下,當一個命令改變系統狀態時,它就會有副作用。而查詢只是返回一個計算好或系統的觀測狀態的值,並不會有任何改變,因此沒有任何副作用。
例如當你呼叫一個函式getAmount(),你希望它只是返回的金額,而不會同時改變系統內狀態。同樣,當你呼叫setAmount() 時,它會有副作用,你期望它只是改變系統的狀態。但你不會期望setAmount()同時還返回修改後的金額。(單一職責)
命令查詢分離CQS/CQRS的定義:改變狀態的函式不應該返回值,函式返回值不應該改變狀態。
這個術語是由Bertrand Meyer在他的“ 物件導向軟體構造”一書中創造的。
優點
遵循此分離的優點之一是,您可以輕鬆地識別函式是否具有副作用。
int m(); // 查詢(無副作用)
void n(); //命令(有副作用)
看看下面的程式碼,它是命令還是查詢?顯然,它改變了系統的狀態。
User u = UserService.login(username, password);
這是一個login函式呼叫,實現登陸功能職責,為什麼它在登陸時還返回使用者物件?下面這樣查詢使用者函式實現返回使用者物件不是更簡單嗎?
User u = UserService.getUser();
當命令更改狀態出錯時,login()函式是返回錯誤程式碼還是丟擲異常?最好是丟擲異常,這樣能夠保持login()命令返回的還是約定void。
儘管CQS在大多數時候都工作良好,但也有例外:
Element e = Stack<Element>.pop(); // 有態查詢
這裡pop()是一個堆疊彈出函式,彈出不但改變了堆疊集合內部狀態,而且同時返回了彈出的值,這是一個命令和查詢混合在一起的案例,當然可以透過純函式方式來處理這種集合處理。
最後總結一下:
1.命令是返回void,而查詢是返回值。
2.使用異常替代函式直接返回錯誤狀態。
正如馬丁·福勒所說,如果語言本身支援這些概念將是會很好。該語言可以檢測狀態改變方法,或者至少允許程式設計師標記它們。但是我們還沒有看到支援這種標記的語言或IDE。
相關文章
- 命令查詢職責分離 - CQRS
- CQRS命令查詢分離架構的多種形式實現 - Kapil架構API
- ffmpeg命令分類查詢
- 資料的儲存和查詢分離不利查詢效能 - thenewstack
- 命令列的藝術命令列
- 離線查詢與線上查詢
- 危險!水很深,讓叔來 —— 談談命令查詢權責分離模式(CQRS)模式
- 查詢命令
- 查詢——二分查詢
- 二分查詢(一)——純粹的二分查詢
- 視覺爆炸的藝術 | 《地平線:黎明時分》藝術賞析視覺
- Android資料庫高手祕籍(7):體驗LitePal的查詢藝術Android資料庫
- MySQL的分頁查詢MySql
- Oracle的分頁查詢Oracle
- Lucene的分頁查詢
- 分組查詢
- Python查詢-二分查詢Python
- 分庫分表後的分頁查詢
- mysql-分組查詢-子查詢-連線查詢-組合查詢MySql
- 查詢演算法__二分查詢演算法
- [Mysql 查詢語句]——分組查詢group byMySql
- 順序查詢和二分查詢
- 二分查詢 | 二分查詢的一種推薦寫法
- sql常用查詢命令SQL
- 檔案查詢命令
- 程式碼審查的藝術:Dropbox 的故事
- Elasticsearch 分頁查詢Elasticsearch
- group by分組查詢
- ssh 分頁查詢
- oracle分頁查詢Oracle
- 二分查詢
- 離譜的 CSS!從錶盤刻度到藝術剪紙CSS
- Windows+Pycharm+Flask+Vue+Element-Plus 前後端分離實現分寫查詢功能WindowsPyCharmFlaskVue後端
- Oracle總結【SQL細節、多表查詢、分組查詢、分頁】OracleSQL
- 命令列的藝術 (GitHub 星標 6 萬多)命令列Github
- elasticsearch查詢之大資料集分頁查詢Elasticsearch大資料
- 查詢演算法之二分查詢演算法
- linux下的find檔案查詢命令與grep檔案內容查詢命令Linux