如今,每一个开发人员都很熟悉MVC标准体系结构设计模式。大多数的应用程序都是基于这种体系结构进行建立的。它容许咱们建立可扩展的大型企业应用程序,但近期咱们还听到了另外的一些有关于CQRS/ES的相关信息。这些方法应该被放在MVC中一块儿使用吗?他们能够解决什么问题?如今,让咱们一块儿来看看CQRS/ES是什么,以及他们都有哪些优势和缺点。数据库
CQRS(Command Query Responsibility Segregation)是一种简单的设计模式。它衍生与CQS,即命令和查询分离,CQS是由Bertrand Meyer所设计。按照这一设计概念,系统中的方法应该分为两种:改变状态的命令和返回值的查询。Greg young将引入了这个设计概念,并将其应用于对象或者组件当中,这就是今天所要将的CQRS。它背后的主要思想是应用程序更改对象或组件状态(Command)应该与获取对象或者组件信息(Query)分开。设计模式
下面,将通一张图来讲明应用程序中有关CQRS部分的组成结构:服务器
Commands(命令)—表示用户的操做意图。它们包含了与用户将要对系统执行操做的全部必要信息。markdown
Query(查询):表示用户实际可用的应用程序状态。获取UI的数据应该经过这些对象完成。架构
下面咱们将介绍有关CQRS的诸多优势,它们是:app
尽管使用CQRS模式具备上述诸多的优势,可是在使用前还须要慎重考虑。对于只具备简单域的简单项目,其UI模型与域模型紧密联系的,使用CQRS反而会增长项目的复杂度和冗余度,这无疑是过分的设计项目。此外,对于数据量较少或者性能要求较低的项目实施CQRS模式不会带来显著的性能提高。框架
有这样一个案例,咱们想要检索任何一个域对象的历史状态数据,并且在任什么时候间均可以生成统计数据。咱们想要检查上个月、上个季度或者过去任什么时候间的状态汇总。想要解决这个问题并不容易。咱们能够在特定的时间范围内将额外的数据保存在数据库中,但这种方法也存在一些缺点。咱们不知道范围应该是什么样子,以及将来统计数据须要哪些数据项。为了不这些问题,咱们能够天天为全部聚合建立快照,但它们一样会产生大量的冗余数据。异步
Event Sourcing(ES)彷佛是目前解决这些问题的最佳方案。Event Sourcing容许咱们将Aggregate(聚合)状态的每个更改事件保存在Event Store的事件存储库中。经过Command Handler将事件写入到事件存储库中,并处理相关的逻辑。要建立Aggregate(聚合)对象的当前状态,咱们须要运行建立预期域对象的全部事件并对其执行全部的更改。下面咱们将经过一张图来讲明这一架构设计方式:oop
下面咱们将列举一些使用ES的优势:post
**Aggregate(聚合)**一词在本文中屡次被说起,那它究竟是什么意思?**Aggregate(聚合)**来自于领域驱动设计(DDD)的一个概念,它指的是始终保持一致状态的实体或者相关实体组。咱们能够简单的理解为接收和处理Command(包含Command Handler)的一个边界,而后根据当前状态生成事件。在一般状况下,Aggregate root(聚合根)由一个域对象构成,但它能够由多个对象组成。咱们还须要注意整个应用程序能够包含多个Aggregate(聚合),而且全部事件都存储在同一个存储库中。
CQRS/ES能够做为特定问题的解决方案。它能够在标准N层架构设计的应用程序的某些层中进行引入,它能够解决非标准问题,常规架构中咱们所拿到的是最终状态,在不少状况下,当然当前状态很重要,但咱们还须要知道当前状态是如何产生的。CQRS和ES两种概念应该一块儿使用吗?事实代表,并无。咱们想要统计任什么时候间范文内的域对象状态,而写库只能存储当前状态。引入CQRS并没能帮助咱们解决这一问题。在下一章节中,咱们将引入Axon框架,Axon框架时间了CQRS/ES,用于解决某些域对象的一些特定问题,尤为是收集历史统计数据。咱们将阐述如何使用Axon框架实现CQRS/ES并实现与Spring Boot应用程的整合。
做者:LukaszKucik ,译:谭朝红,原文:CQRS and Event Sourcing as an antidote for problems with retrieving application states