当团队检查这两个限界上下文的领域模型时,发现两个上下文都不知道定价。订单和注册上下文创建了一个订单,其中列出了注册者请求的不同座位类型的数量。支付绑定上下文只是将总数传递给外部支付系统。在某个时候,系统需要在调用支付流程之前计算订单的总数。
团队考虑了两种不同的方法来解决这个问题:支持自治和支持权威。
支持自治自治方法将计算订单总数的任务分配给订单和注册限界上下文。它在需要执行计算时不依赖于另一个限界上下文,因为它已经拥有了必要的数据。在过去的某个时候,它将从其他限界上下文(例如会议管理限界上下文)收集所需的定价信息并缓存它。
这种方法的优点是订单和注册限界上下文是自治的。它不依赖于另一个限界上下文或服务的可用性。
缺点是价格信息可能已经过时。业务客户可能在会议管理限界上下文中更改了定价信息,但该更改可能尚未到达订单和注册有界上下文中。
支持授权在这种方法中,计算订单总数的系统部分在执行计算时从限界上下文中(例如会议管理限界上下文中)获取定价信息。订单和注册限界上下文仍然可以执行计算,或者可以将计算委托给系统中的另一个限界上下文或服务。
这种方法的优点是,每当计算订单总数时,系统总是使用最新的定价信息。
缺点是,当需要确定订单总数时,订单和注册限界上下文依赖于另一个限界上下文。它要么需要查询会议管理限界上下文以获得最新的定价信息,要么调用另一个执行计算的服务。
**在自治和授权之间选择这两种之间的选择是一个业务决策。场景的特定业务需求决定采用哪种方法。自治通常是大型在线系统的首选。
Jana(软件架构师)发言:这个选择可能会根据系统的状态而改变。考虑一个超额预订的场景。当大量会议席位仍然可用时,自治策略可能会在正常情况下进行优化,但是随着特定会议的满员,系统可能需要变得更加保守,并使用关于座位可用性的最新信息来支持授权。
会议管理系统计算订单总数的方法是选择自治而不是授权的一个例子。
Carlos(领域专家)发言:对于Contoso来说,自治是明确的选择。注册者因为其他一些限界上下文挂了而不能购买座位是一个严重的问题。无论怎样,我们并不真正关心业务客户修改的定价信息和用于计算订单总数的新定价信息之间是否存在短暂的延迟。
下面的计算汇总部分描述了系统如何执行此计算。
读端的实现方法在前几章对读端进行的讨论中,您看到了团队如何使用基于sql的存储来从写端对数据进行非规范化的映射。
您可以为读取模型数据使用其他存储机制。例如,您可以使用文件系统或Azure table或blob来存储。在订单和注册限界上下文中,系统使用Azure blob存储关于座位分配的信息。
Gary(CQRS专家)发言:当您为读端选择底层存储机制时,除了要求读端上的查询方便且高效外,还应该考虑与存储相关的成本(尤其是在云中)。 备注:请参阅SeatAssignmentsViewModelGenerator类,以了解如何将数据持久化到blob存储,以及SeatAssignmentsDao类,以了解UI如何检索数据以供显示。 最终一致性
在测试期间,团队发现了一个场景,在这个场景中,注册者可能会看到操作中最终一致性的证明。如果注册者将参会者分配到订单上购买的座位,然后快速导航到查看分配,那么有时该视图只显示部分更新。然而,刷新页面会显示正确的信息。这是因为记录座位分配的事件传播到读模型需要时间,有时测试人员会过早地查看从读模型查询的信息。
尽管生产系统更新读取模型的速度可能比本地运行的应用程序的调试版本要快,但是团队决定在视图页面中添加一个注释,警告用户这种可能性。