一、DDD的基本概念和设计流程

1、DDD的概念

DDD: Domain Driven Design

Eric Evans:《领域驱动设计:软件核心复杂性应对之道》里面一段话:

​ DDD先对业务领域进行分析,建立领域模型,根据领域模型驱动代码设计

2、使用DDD的原因和好处

image-20211012132404713

最重要的一点是,DDD是类似于微服务中台落地的指导思想,这也是DDD为什么这些年比较火的原因。

我们先来看一下DDD的基本概况。

image-20211012131733728

在DDD里面提供了很多专用名词,像领域、子域、通用语言、限界上下文、领域服务、领域事件、实体、聚合等。

了解这些概念,不仅有助于我们了解DDD的基本思想,同时也更便于我们和其他团队的沟通。图中标识的实际上就是领域的父子或者层级关系,我们实际上通过这个图已经可以看出分治思想的体现了,而DDD实际上就是将大领域逐步的拆分细化的过程。

(1)领域、子域

领域、子域 : 通过不断解决小领域,最终产生大领域的解决方案 -> 分而治之

领域: 指定服务内待解决的业务问题

子域:更小,更细化的领域

如: 报告解读领域来举个例子

报告解读领域 —> 心电数据提交域交易域解读域结算域用户增长域

​ **交易域 ** —-> 订单域支付域退款域

​ 就这样 领域、子域、子子域能力去做串联,报告解读领域的问题就自然而然的解决了。

领域种类

下面来介绍一下领域类型,在DDD中领域类型包括三种:核心域、通用域和支撑域。

  • **核心域:**就是公司和团队的核心竞争力。

  • **通用域:**指的是通用能力。

    ​ 举个例子:比如说公司有个算法团队,报告解读领域本身是有算法结论辅助需求的,那么在报告解读领域中,算法域可以作为通用域来提供报告解读的通用能力。

  • **支撑域:**指的就是非核心、非通用的领域。

(2)通用语言、限界上下文

通用语言: 通过团队的沟通达成共识,能够简单、清晰、明确地表述业务含义和规则的语言,可以列成一个领域的唯一件。

限界上下文: 用来封装通用语言和领域对象,提供上下游边界,保证在领域之内的一些术语、业务对象有个明确的含义,无二义性。本质上就是个领域

基础原则:第一点就是组织架构(不能跨领域架构);第二个就是要去除歧义(二义性)。

(3)实体、值对象、聚合

实体: 拥有唯一标识符、且标识符在历经各种状态变更后仍能保持一致的一类对象。

值对象:没有标识符或状态流转,承载多个相关属性集合的一类对象。

聚合:实体和值对象协同工作的组织

举个例子 :

  1. 多个商品 –> 订单(买家信息,金额等) –> 订单详情(横表,各个商品信息)

​ 值对象: 买家信息

​ 聚合: 创建订单和创建订单详情是一起

  1. 用户领域

    实体: 用户(买家信息)

(4)领域事件

领域事件: 当某个领域触发变更后,通知其他领域的事件 。 只是通知或触发,而不参与其中,达到解耦目标。

举个例子:

​ 订单支付成功之后 —> 增加用户积分

​ 订单实体–> 发出订单支付成功的事件,用来通知用户的积分予以去做增长积分的一个行为。

image-20211012131733728

我们再返回来看一下之前的图,在这个图里面领域和子域是N:1的,子域和限界上下文是N:1的,限界上下文和聚合是N:1的,聚合和实体、指对象也是N:1的。

相信通过这个图和前面的讲解,大家对DDD的基础概念有更清晰、更明确的认识。

在DDD里面会有两种设计:战略设计、战术设计。

战略设计

指的是从业务视角里面,去划定领域边界和限界上下文;

战术设计

是从技术的视角,去做实体、值对象、领域服务、领域事件等的设计。

image-20211012152131733

3、DDD的设计流程

下面看一下DDD的设计流程。

image-20211012152726950

在产品需求产出之后, DDD建议我们通过事件风暴的方式去做需求分析、领域梳理、确定限界上下文这三个步骤,这三个步骤实际上就是DDD设计的全部,而限界上下文确定之后,它可以用来指导我们系统架构设计,而领域梳理其实可以指导我们去做详细设计(包括数据模型的设计,接口设计等)。

事件风暴的参与者一般是希望当前领域所有的成员都可以去参加,包括研发、产品、测试以及领域专家,而在这里领域专家有可能是开发、测试、产品中的一员。