购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.5
应用服务

在上一章中,我们已经明确了应用服务可以分成命令服务和查询服务两大类,也理解了应用服务作为一种外观类在用户界面与领域模型之间起到的交互作用。本节关注在HealthMonitor案例系统中如何为每个限界上下文合理设计应用服务。相比于查询服务,命令服务的实现过程更为复杂,是我们首先要讨论的对象。

3.5.1 HealthMonitor命令服务

在介绍命令服务之前,我们先来讨论命令与领域事件之间的关系,如图3-18所示。

图3-18 命令和领域事件的关系示意图

从数据流转角度看,命令实际上是对限界上下文中聚合对象的一种输入请求,该请求会更新聚合的状态。而领域事件则可以被看作聚合的一种输出,传播限界上下文的状态变更。

因此,在设计领域模型时,命令和事件往往是成对出现的。这里以Monitor限界上下文为例,给出命令与事件之间的映射关系,如图3-19所示。

图3-19 Monitor限界上下文中的命令和事件映射关系示意图

在图3-19中,我们从接收一个用于申请健康监控的ApplyMonitorCommand命令对象开始,HealthMonitor聚合处理完这个命令对象之后会发布一个MonitorInitialized领域事件。然后,用户想要生成健康计划时,就会使用CreatePlanCommand命令对象,当处理完这个命令对象之后,HealthMonitor聚合会发布对应的PlanGenerated事件。

明确了命令对象的使用者是聚合,接下来就需要创建命令服务。在命令服务中,命令对象通常由位于更上层的REST API构建并传递。命令对象相关的各组件之间的关系如图3-20所示。

图3-20 命令服务相关对象的处理关系

在图3-20中,我们可以清晰地看到各种对象的职责,如下。

❑REST API:负责创建命令对象,调用命令服务。

❑命令服务:负责传入命令对象,创建聚合对象并调用资源库。

❑聚合对象:负责处理命令对象并生成领域事件。

同样,我们以Monitor限界上下文为例,给出该上下文中的命令服务,如图3-21所示。

图3-21 Monitor限界上下文中的命令服务

而对整个HealthMonitor案例系统而言,其他3个限界上下文的命令服务如图3-22所示。

图3-22 HealthMonitor案例系统中的命令服务

3.5.2 HealthMonitor查询服务

在DDD中,查询服务的定位很明确,就是用来获取限界上下文当前状态的。在命令服务和领域事件的基础上,我们把查询服务也添加到限界上下文中,如图3-23所示。

图3-23 限界上下文和查询服务

针对查询服务的输入,通常会构建专门的查询对象。例如,针对Monitor限界上下文,如果想要获取用户健康监控信息,就可以构建一个以HealthMonitorQuery命名的查询对象,该查询对象可能会包含用户的身份信息以及时间范围等各种查询条件。当然,有些查询操作的输入参数非常简单,我们也可以不构建专门的查询对象。围绕查询对象,各组件之间的关系如图3-24所示。

图3-24 查询服务相关对象的处理关系

在图3-24中,我们注意到查询服务的操作流程还是比较简单的。相比于命令服务,查询服务的主要交互对象就是资源库,一般都会直接从资源库中获取目标数据并进行必要的封装,而不需要与聚合对象形成复杂的交互关系。

对查询服务的输出而言,有时候我们也会构建专门的查询结果(QueryResult)对象。举一个典型的例子,假如我们希望从Monitor限界上下文中获取健康监控的概要信息,而不是完整的HealthMonitor数据。在这个查询操作中,健康监控概要信息与健康监控聚合对象HealthRecord在字段上存在差异,所以我们需要提供一个更加适合本次查询操作的健康监控概要信息对象HealthMonitorSummary。同样,在其他限界上下文中,如果我们也希望更加灵活地获取想要的业务数据,那么就可以构建各种形式的查询结果对象。

这里,我们继续以Monitor限界上下文为例,给出该上下文中的查询服务,如图3-25所示。

图3-25 Monitor限界上下文中的查询服务

在HealthMonitor案例系统中,各个限界上下文都有对应的查询服务。这些查询服务在类层结构上都比较简单,这里不再一一展开讨论。 vIPVWSGh6d3Z+DCjgy6EdyN8v+RKBbtT83CGTZ0d5bVp5yL+/DiqFy0OfIcna6u3

点击中间区域
呼出菜单
上一章
目录
下一章
×