在介绍领域驱动设计之前,先请大家回答一个问题:什么是领域。所谓领域,本质上是对现实世界问题的一种统称,是一种业务开展的方式,体现了一个组织所做的所有事情,覆盖一切业务范围,包含所有组织活动。我们在开发软件时面对的就是各种不同的领域。例如,常见的电商系统包含商品、订单、库存和物流等业务概念,而医疗健康系统则关注挂号、就诊、用药、健康报告等业务场景。这些业务概念和业务场景都属于领域。
领域概念的提出,一方面从业务的角度体现了系统的功能和价值,另一方面从技术的角度为我们提供了一种设计思想。本节将从现实问题出发讨论面向领域的设计思想。
让我们先从一个业务场景开始说起。在日常生活的就医场景中,我们知道为了完成一次就医过程,用户需要预约挂号,向医生讲述身体症状,做各种检查并获取报告,根据检查结果用药等。把这些步骤抽象成一个问题空间就是“就诊”。我们针对这一场景设计一个系统,所有的环节都是为了帮助用户更好地实现就诊过程,那么,如何针对就诊这个问题空间提供解决方案呢?这就需要我们对系统进行建模,得出指导系统开发的业务模型。系统建模是一个复杂的话题,围绕这一话题业界形成了不同的建模方法,而DDD在系统建模领域占有非常重要的一席之地。
1.业务模型
下面分析一个完整的业务模型应该包含哪些组成部分。在本书中,我们把业务模型拆分成7个维度,如图1-1所示。
图1-1 业务模型的7个维度
在图1-1中,我们通过7个维度来阐述什么是业务模型,下面逐一说明。
❑业务描述。业务模型需要通过简洁且通用的语言进行描述,从而确保与模型相关的所有人都能够对模型所代表的业务场景和需求达成统一认识。
❑业务拆分。业务场景的复杂度决定了业务模型中功能组件的数量和关联关系,我们需要通过拆分来明确各个组件的功能之间的边界。
❑业务对象。在一个业务场景中势必存在一组业务对象,这些业务对象通过一定的交互关系构成具体的业务场景。
❑业务规则。在一个业务模型中,内部的核心逻辑通过一系列的业务规则来展现,业务规则代表具体领域的业务价值。
❑业务状态。每个业务场景都是有状态的,这些状态构成了业务处理的流程和顺序,也是我们对业务进行建模的重点对象。
❑业务数据。所有业务模型都会产生数据,而且业务规则和业务状态的设计在很大程度上是围绕业务数据的处理过程来展开的,我们需要把核心的业务数据进行持久化保存。
❑业务外观。一个业务模型需要和客户端、其他业务模块及第三方外部系统进行集成,这就需要开放一定的交互入口,我们把这部分内容称为业务外观。
领域驱动设计针对业务模型为上述7个维度的问题给出了对应的设计方法,我们会在1.2节中详细讲解。
2.系统复杂度
我们知道,任何软件系统的发展都是从简单到复杂、从集中到分散的过程。在系统诞生的初期,我们习惯构建单一、内聚和全功能式的系统,因为这样的系统就能满足当时业务的需求。当业务发展到一定阶段后,集中化系统会露出诸多弊端,功能拆分及服务化的思想和实践就会被引入。而当系统继续演进后,团队规模也随之扩大,由于分工模糊且业务复杂度不断上升,系统架构逐渐腐化,直到系统不能承受任何改变,就到了需要重构拆分的阶段。系统的推倒重来意味着重复从简单到复杂、从集中到分散的过程,如图1-2所示。
图1-2 系统架构演进的规律
图1-2所示的是系统架构演进的一种客观规律,我们无法完全避免,但可以通过一定手段减缓整个过程的发展速度。本质上,这是一个如何应对系统复杂度的问题。
从软件开发和架构设计的角度而言,领域概念的提出是为了更好地对业务概念和业务场景进行抽象,从而为系统实现过程提供明确的领域模型和清晰的模型边界。通过引入面向领域的概念以及对应的设计方法,我们可以明确软件系统的关注点,并通过功能拆分有效降低系统复杂度。
现在,我们已经明确了领域的概念,也抽象出了业务模型的各个维度,而开发人员对领域和业务模型的思考方法体现在设计维度上。在领域驱动设计中,有两个主要的设计维度,即战略设计维度和战术设计维度。
战略设计维度关注如何设计领域模型以及如何对领域模型进行划分,其目的在于清楚地界定不同的系统与业务关注点。战略维度面向业务,层次较高,偏重对业务架构的梳理,考虑如何把业务架构和技术架构进行整合。
战术设计维度关注如何从技术的层面指导开发人员具体地实施领域驱动设计,以及如何在领域模型的基础上采用特定的技术工具来开发系统。显然,战术维度偏向技术实现,考虑技术架构的设计和展现方式。
战略维度和战术维度的整合为开发人员提供了一套通用的建模语言和术语,展示了基于领域驱动的架构设计方法和实现领域驱动设计的各项关键技术,如图1-3所示。我们会在接下来的内容中对领域驱动设计的两大维度进行详细讲解。
图1-3 领域驱动设计的两大维度
总的来说,领域驱动设计提供的是一种软件开发方法,强调开发人员与领域专家进行协作并交付业务价值,强调把握业务的高层次方向,也强调采用系统建模工具和方法来满足技术需求。领域驱动设计思想的核心就是认为系统架构的设计应该是业务架构和技术架构相结合的过程,并提供了一系列设计方法和模式来确保实现这一过程。