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)某个事件被触发。