命令——首先,触发命令是唯一改变系统状态的方法。命令负责引起所有的对系统的改变。如果没有命令,系统状态保持不变!命令不应该返回任何值。我使用两个类来实现它:Command 和 CommandHandler 。Command 只是一个普通的对象,CommandHandler 将它用于表示某些操作的输入值(参数)。我认为命令是简单地调用领域模型中的特定操作(不一定是每个命令都有的操作)。
查询——同样的,查询是一个读操作。它读取系统的状态,过滤,聚总,以及转换数据,并将其转化为最有用的格式。它可以执行多次,而且不会影响系统的状态。我之前是使用一个有一些 Execute(…) 函数的类来实现它,但是现在我认为分离成 Query 和 QueryHandler/QueryExecutor 可能会更有用。
事件溯源是与 CQRS 一起提出的一个概念,通常被标识为 CQRS 的一部分。ES(Event Sourcing)的概念很简单:我们的领域生成的事件表示系统中的每一个更改。如果我们从系统开始记录每一个事件,而且从最初状态开始重现,我们会得到系统的当前状态。它与银行账户的事务相似;我们可以从空账户开始,重现每一个单独的事务,然后(有希望地)得到当前的余款。因此,如果我们已经存储了所有的事件,我们能得到系统的当前状态。
虽然 ES 是存储系统的状态的一种很好的方法,但是 CQRS 并不一定需要它。对于 CQRS ,领域模型实际上如何存储并不重要,而且这只是一个选项。
在我第一次尝试 CQRS 时,我使用了 WRITE 模型来构建查询……它是 OK 的(或者至少是有效的)。过了一段时间,我们到达了项目中需要花费大量时间进行查询的地方。为什么?因为我们是程序员,优化是我们的第二天性。我们将模型设计为规范化,因此我们的读取端受到连接的影响。我们被迫预先计算一些报告的数据以保持快速。这很有趣,因为实际上我们引入了缓存。在我看来,这是读取模型的最佳定义:它是一个合法的缓存。由于我们必须发布项目,而非功能性的需求没有得到满足,因此,缓存是通过设计来实现的。
标签读取模型可以建议它存储在一个数据库中,仅此而已。实际上读取模型可能非常复杂,你可以使用图形数据库来存储社会连接,使用 RDBMS 来存储财务数据。这是一个多语言持久性很自然的地方。
评论删除后,数据将无法恢复
评论(4)