旅程3:订单和注册限界上下文 CQRS之旅的第一站 “寓言家和鳄鱼是一样的,只是名字不同” --约翰·劳森 描述:
订单和注册上下文有一部分职责在会议预订的过程中,在此上下文中,一个人(注册者)可以购买特定会议的座位。还可以为已购买的座位分配与会者的名称(这在第5章“准备发布V1版本”中进行了描述)。
这是我们CQRS旅程的第一站,因此团队决定实现一个核心的、但自包含的系统部分——订单和注册。对与会者来说,注册过程必须尽可能地轻松。该流程必须确保业务客户能够预订到尽可能多的座位,并为他们提供灵活的,在会议上为不同类型的座位设置价格的功能。
因为这是团队处理的第一个限界上下文,所以我们还实现了系统的一些基础设施来支持领域域的功能。包括命令和事件消息总线以及聚合的持久化机制。
备注:本章描述的Contoso会议管理系统并不是该系统的最终版本。本此旅程描述的是一个过程,因此一些设计决策和实现细节在过程的后期会发生变化。这些变化将在后面的章节中描述。
在将来的某个旅程中,对这个限界上下文的改进计划包括支持等待列表(如果没有足够的座位可用,对座位的请求将放在等待列表中),以及允许业务客户为座位类型设置各种类型的折扣。
备注:在这个版本中没有实现等待列表,但是社区成员正在开发这个特性和其他特性。任何带外发布和更新都将在“CQRS之旅”网站上公布。
本章的工作术语定义:本章使用了一些术语,我们将在稍后定义它们。有关更多细节和可能的替代定义,请参阅参考指南中的“深入CQRS和ES”。
Command(命令):命令是要求系统执行更改系统状态的操作。命令是必须服从(执行)的一种指令,例如:MakeSeatReservation。在这个限界上下文中,命令要么来自用户发起请求时的UI,要么来自流程管理器(当流程管理器指示聚合执行某个操作时)。单个接收方处理一个命令。命令总线(command bus)传输命令,然后命令处理程序将这些命令发送到聚合。发送命令是一个没有返回值的异步操作。
Gary(CQRS专家)发言:有一些讨论是关于优化的可能性,这涉及到命令不同的定义,这些不同点是微小的。请参阅第6章“系统的版本控制”。
Event(事件):事件就是系统中发生的一些事情,通常是一个命令的结果。领域模型中的聚合会引发(raise)事件。多个事件订阅者(subscribers)可以处理特定的事件。聚合将事件发布到事件总线, 处理程序订阅特定类型的事件,事件总线(event bus)将事件传递给订阅者。在这个限界上下文中,唯一的订阅者是流程管理器。
流程管理器。在这个限界上下文中,流程管理器是一个协调领域域中聚合行为的类。流程管理器订阅聚合引发的事件,然后遵循一组简单的规则来确定发送一个或一组命令。流程管理器不包含任何业务逻辑,它唯一的逻辑是确定下一个发送的命令。流程管理器被实现为一个状态机,因此当它响应一个事件时,除了发送一个新命令外,还可以更改其内部状态。
Gregor Hohpe和Bobby Woolf合著的《Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions》(Addison-Wesley Professional, 2003)书中312页讲述了流程管理器实现模式。我们的流程管理器就是依照这个模式实现的。
对于刚接触代码的人来说,跟踪命令和事件在系统中的流动是很困难的。第4章“扩展和增强订单和注册有界上下文”中的“对测试的影响”一节,讨论了怎样可以帮助你搞清楚它们。
在这个限界上下文中,流程管理器可以接收命令,也可以订阅事件。
Gary(CQRS专家)发言:在订单和注册限界上下文中,起初,提到流程管理器,团队把它当作一个Saga(一种可用于处理事务的模式),要了解后来为什么我们决定更改术语,请参阅本章后面的“模式和概念”一节。
注:参考指南里包含了CQRS相关术语的附加定义和解释。
领域定义(通用语言)下面的列表定义了团队在开发此订单和注册有界上下文时使用的关键领域相关术语。