DDD领域驱动设计(一)

简介

DDD 是一种处理高度复杂领域的设计思想,它试图分离技术实现的复杂性,并围绕业务概念构建领域模型来控制业务的复杂性,以解决软件难以理解,难以演进的问题。DDD 不是架构,而是一种架构设计方法论,它通过边界划分将复杂业务领域简单化,帮我们设计出清晰的领域和应用边界,可以很容易地实现架构演进。

核心思想

通过领域驱动设计方法定义领域模型,从而确定业务边界和应用边界,保证业务模型与代码模型的一致性。

DDD设计

战略设计

战略设计主要从业务视角出发,建立业务领域模型,划分领域边界,建立通用语言的限界上下文,限界上下文可以作为微服务设计的参考边界。

战术设计

战术设计则从技术视角出发,侧重于领域模型的技术实现,完成软件开发和落地,包括:聚合根、实体、值对象、领域服务、应用服务和资源库等代码逻辑的设计和实现。

领域和子域

领域

按照一定的规则将业务领域进行细分,当领域细分到一定的程度后,DDD 会将问题范围限定在特定的边界内,在这个边界内建立领域模型,进而用代码实现该领域模型,解决相应的业务问题。简言之,DDD 的领域就是这个边界内要解决的业务问题域。

子域

领域可以进一步划分为子领域。我们把划分出来的多个子领域称为子域,每个子域对应一个更小的问题域或更小的业务范围。

核心域、通用域和支撑域

在领域不断划分的过程中,领域会细分为不同的子域,子域可以根据自身重要性和功能属性划分为三类子域,它们分别是:核心域、通用域和支撑域。

核心域

决定产品和公司核心竞争力的子域,它是业务成功的主要因素和公司的核心竞争力。

通用域

没有太多个性化的诉求,同时被多个子域使用的通用功能子域。如:身份认证,权限等

支撑域

既不包含决定产品和公司核心竞争力的功能,也不包含通用功能,但是是必需的子域。如:数据字典等系统

通用语言和限界上下文

通用语言

在事件风暴过程中,通过团队交流达成共识的,能够简单、清晰、准确描述业务涵义和规则的语言。通用语言是团队统一的语言,不管你在团队中承担什么角色,在同一个领域的软件生命周期里都使用统一的语言进行交流。

限界上下文

为了避免通用语言同样的概念或语义在不同的上下文环境中产生歧义,DDD 在战略设计上提出了“限界上下文”这个概念,用来确定语义所在的领域边界。

通用语言确定了项目团队内部交流的统一语言,而这个语言所在的语义环境则是由限界上下文来限定的,以确保语义的唯一性。

领域专家、架构师和开发人员的主要工作就是通过事件风暴来划分限界上下文。限界上下文确定了微服务的设计和拆分方向,是微服务设计和拆分的主要依据。如果不考虑技术异构、团队沟通等其它外部因素,一个限界上下文理论上就可以设计为一个微服务。

实体和值对象

实体

拥有唯一标识符,且标识符在历经各种状态变更后仍能保持一致。对这些对象而言,重要的不是其属性,而是其延续性和标识,对象的延续性和标识会跨越甚至超出软件的生命周期。我们把这样的对象称为实体。

值对象

通过对象属性值来识别的对象,它将若干个用于描述目的、具有整体概念和不可修改的属性组合为一个概念整体。在 DDD 中用来描述领域的特定方面,并且是一个没有标识符的对象。在领域建模的过程中,值对象可以保证属性归类的清晰和概念的完整性,避免属性零碎。本质上就是一个集。

聚合和聚合根

聚合

业务和逻辑紧密关联的实体和值对象组合,构成聚合,聚合是数据修改和持久化的基本单元,每个聚合对应一个仓储,实现数据的持久化。聚合有一个聚合根和上下文边界,这个边界根据业务单一职责和高内聚原则,定义了聚合内部应该包含哪些实体和值对象,而聚合之间的边界是松耦合的。聚合在 DDD 分层架构中属于领域层,领域层包含了多个聚合,共同实现核心业务逻辑。跨多个实体的业务逻辑通过领域服务来实现,跨多个聚合的业务逻辑通过应用服务来实现。

聚合根

聚合根也称为根实体,聚合根的主要目的是为了避免由于复杂数据模型缺少统一的业务规则控制,而导致聚合、实体之间的数据不一致的问题。首先它作为实体,拥有实体的属性和业务行为,实现自身的业务逻辑。其次它作为聚合的管理者,在聚合内部负责协调实体和值对象按照固定的业务规则协同完成共同的业务逻辑。聚合之间通过聚合根 ID 关联引用,如果需要访问其他聚合的实体,就要先访问聚合根,再导航到聚合内部实体,外部对象不能直接访问聚合内实体。

领域事件

领域事件是微服务解藕的关键。在事件风暴(Event Storming)时,除了命令和操作等业务行为以外,还有一种非常重要的事件,这种事件发生后通常会导致进一步的业务操作,在 DDD 中这种事件被称为领域事件。

一次业务操作设计多个聚合状态的更改,应采用领域事件的最终一致性。领域事件驱动设计可以切断领域模型之间的强依赖关系。

领域事件处理包括:事件构建和发布、事件数据持久化、事件总线、消息中间件、事件接收和处理等。

事件风暴

事件风暴是一项团体活动,领域专家与项目团队通过头脑风暴的形式,罗列出领域中所有的领域事件,整合之后形成最终的领域事件集合,然后对每一个事件,标注出导致该事件的命令,再为每一个事件标注出命令发起方的角色。命令可以是用户发起,也可以是第三方系统调用或者定时器触发等,最后对事件进行分类,整理出实体、聚合、聚合根以及限界上下文。它可以快速分析和分解复杂的业务领域,完成领域建模。