1.2.2 领域驱动战略设计
我们先来看领域驱动的战略设计。战略设计包含统一语言和限界上下文这两个核心概念,它们与业务模型的对应关系如图1-23所示。
图1-23 业务模型与战略设计的对应关系
1.统一语言
通俗地说,统一语言(Ubiquitous Language,也称作通用语言)就是团队成员的“行话”,面向的是业务而不是技术。在协作过程中,业务人员和技术人员在意识形态与认知体系上达成一致并不是一件容易的事情,一方面需要领域专家持续介入,另一方面需要开发者具备对业务领域的基本思考方法。
统一语言的建立通常并不是一步到位的,而是分层次持续演进的。例如,考虑一个用户健康监控和管理的业务场景,业务人员和开发人员经过初步沟通,得到如下统一语言。
构建统一的健康监控功能,用户可以通过这一功能管理自己的健康信息。
在上述场景下,对原始需求的描述构成了系统的最高层次的统一语言,后续从业务到技术的各个层次的统一语言都将由此展开。而在开发人员与业务人员进一步沟通之后,得到如下细化的统一语言。
用户在申请健康检测时会生成一个健康检测单,同一个用户在上一个健康检测单没有完成之前无法申请新的检测单。
用户在申请健康检测单时提供自己的既往病史及目前的症状描述,然后系统根据用户的这些输入信息生成一个健康计划,健康计划被看作管理用户健康数据的一种执行媒介。
一个用户在同一时间只能有一份生效的健康计划,如果用户对系统自动生成的健康计划并不满意,可以重新申请生成健康计划。
健康计划的具体内容包括计划的制定医生、计划的描述、执行的周期、需要用户执行的健康任务列表等数据。
健康检测的结果表现为一种可以量化的健康分,该健康分会根据用户执行健康任务的完成情况不断更新。用户可以通过健康分判断自己的健康状况。
上述对业务场景的描述构成了第二层级的统一语言,我们可以从这些描述中提取大量有助于开展系统设计工作的关键信息。
统一语言的表现形式可以多样化,常见的有术语表、文档和图、模型语言等。在第3章中,我们将详细介绍统一语言的表现形式。
2.限界上下文
针对业务拆分,我们首先需要引入子域(Sub Domain)的概念。我们可以将领域拆分为多个独立的子域。子域作为系统拆分的切入点,其来源往往取决于系统的特征和拆分的需求,如这些需求属于核心功能、辅助性功能还是第三方功能等。
拆分子域之后,我们需要进一步明确限界上下文(Bounded Context)的概念。限界上下文是DDD中的核心概念,这个概念比较难以理解,我们可以把这个词拆开来进行解释,即限界上下文=限界+上下文。
● 限界。对于任何概念、属性和操作,每个领域模型在特定的业务边界之内具有特定的含义,这些含义只限于这个边界之内,同一个业务概念,在不同的限界上下文中代表着不同的领域模型,这就是“限界”这个名称的由来。
● 上下文。上下文用来表现业务流程的场景片段。随着业务的开展,上下文会因为某些活动的发生而形成场景的边界。
我们来看一个限界上下文的简单示例,如图1-24所示。
图1-24 限界上下文示例
图1-24描述的是一个客服管理系统的业务场景,用户基于某一个订单(Order)发起一个客服工单(Ticket),该工单会交由某一个客服人员(Staff)进行处理。这里出现了3个限界上下文,其中Ticket上下文和Staff上下文中都存在一个Staff对象。两个Staff对象虽然名称相同,也代表着同一个逻辑概念,但在业务建模过程中却有本质性的区别。随着内容的演进,会发现Staff上下文中的Staff是一个聚合(Aggregate)对象,而Ticket上下文中的Staff则是一个实体(Entity)对象。另外,Ticket上下文中的Ticket对象可能依赖Order上下文中的Order对象,但Ticket和Order显然属于不同的业务场景,此时可以发现,通过划分限界可以在很大程度上影响系统的设计和实现。
有了子域和限界上下文,下一步就是将它们整合到一起。每个子域都有自己的限界上下文,可以根据需要有效整合各个限界上下文,从而构成一个完整的领域模型。