Command Query Responsibility Segregation,CQRS 這個架構好象最近部落格園裡讨論得比較多,有幾篇園友的文章很有深度,推薦閱讀:
<a href="http://www.cnblogs.com/yangecnu/p/Introduction-CQRS.html">淺談指令查詢職責分離(CQRS)模式</a>
<a href="http://www.cnblogs.com/netfocus/p/5184182.html">DDD CQRS架構和傳統架構的優缺點比較</a>
CRQS是基于事件驅動的,其主要架構并不複雜,見下圖:

簡單來講,對資料庫的修改操作,UI層隻管發送各種指令(Command),觸發事件(Event),然後由EventHandler去異步處理,最終寫入master DB,對于資料庫的查詢,則查詢slave DB(注:這裡的master db, slave db隻是一個邏輯上的區分,可以是真正的主-從庫,也可以都是一個庫)。 這樣的架構,很容易實作讀寫分離,也易于大型項目的擴充。
項目結構:
package的名稱上大概就能看出用途:
command包定義各種指令,
event包定義各種事件,
handler包定義事件處理邏輯,
model包相當于領域模型
最外層的ToDOItemRunner相當于應用程式入口。
gradle依賴項:
command指令:
這裡我們假設了二個指令:建立指令、完成指令
CreateToDoItemCommand
MarkCompletedCommand
Event事件:
ToDoItemCreatedEvent
EventHandler事件處理
上面的代碼隻是示範,将事件資訊輸出而已,真實應用中,這裡可以完成對db的更新操作。
領域模型model
然後讓Spring将這些東西串在一起,配置檔案如下:
View Code
最後,提供一個舞台,讓整個應用run起來:
輸出結果:
axon架構測試也很容易:
given/when/expectEvents的意思是,給(given)一個事件,然後當(when)某個指令被調用時,期待(expectEvents)某個事件被觸發。