关于DDD的概念笔记

1,438 阅读7分钟

前言

看过很多关于 DDD 的文章, 也买过一些书籍, 但是发现内容冗长, 大部分时间用来理解名词含义, 而忽略里面的设计精华.

下面是我基于极客时间《DDD实战课专栏》整理的一些名词解释, 里面也掺杂了一些个人理解和说明, 希望能对你理解起来有所帮助.

领域和子域

领域顾名思义, 表示的是特定的一种范围

举例说明:

我们把领域比作为整体的业务系统, 在业务系统里面也包含很多子系统(比如用户中心、订单中心、商品中心), 我们将这些子系统称为子域, 是依据领域的范围继续划分出来的更小的业务范围,

在用户中心里面也可以继续划分为VIP和普通用户系统等, 这也就是子域进一步划分为子子域, 这也是正常系统演进的过程.

一个复杂的系统, 通过逐步划分子域, 形成了业务上的拆解, 最终目的是降低业务理解和系统实现的复杂度

如何理解核心域、通用域和支撑域

核心域

可理解为最核心的业务(主线), 基本属于业务的核心竞争力了.

不同公司核心域是不同的, 比如有侧重质量, 有侧重物流服务, 也有客户服务

通用域

被多个子域共同使用的称之为通用域, 比如认证、权限等

支撑域

一些公司个性化的业务

什么是通用语言

通过团队沟通最终达成的共识, 能够简单、清晰、准确的描述我们业务涵义和规则的语言就是通用语言.

简单来说就是可以解决交流障碍问题, 统一产品、研发、测试、运营等人员之间的业务术语交流

通用语言名词给领域对象命名, 比如商品、订单等, 对应实体模型. 动词表示一个动作或事件, 比如下订单、取消订单、订单已取消、订单已付款、浏览商品、加入购物车等

定义好通用语言, 将通用语言中的业务需求转换为的代码实现, 就会非常容易了, 最终实现了 业务语言与代码语言的统一

限界上下文

限界就是领域的边界,而上下文则是语义环境

我们都知道语言的魅力, 一句 今天交作业了没, 在不同的场景下就会赋予不同的含义, 同学问你可能是真的问你交作业了没有, 如果你的女朋友问你, 可能又是另一个含义了.

所以我们必须要明确在一个业务场景下使用的业务语言只有一个含义, 避免理解起来出现二义性, 否则会出现认知偏差, 结果就会沟通起来很累.

只有在限界上下文的条件下, 通用语言才可能会避免出现二义性.

为什么讲 限界上下文可以作为微服务拆分的重要依据?

之前我们讲到划分子域, 划分后我们需要达成通用语言

通用语言永远只表示一个含义, 需要给定一个有效范围(限界上下文, 划分领域边界), 最终可映射一个完成的服务实体.

实体和值对象

实体

每个实体对象都有唯一的 ID。我们可以对一个实体对象进行多次修改,修改后的数据和原来的数据可能会大不相同

更简化的理解为: 商品是商品上下文的一个实体,通过唯一的商品 ID 来标识,不管这个商品的数据如何变化,商品的 ID 一直保持不变,它始终是同一个商品

比如我们在开发电商系统中, 我们可以给定商品实体、订单实体等等, 然后我们再继续围绕这些实体开展工作

值对象

值对象是实体的一部分, 负责延展、扩充实体对象, 属于实体对象的一部分

实体对象映射的是真实的业务对象,具有业务属性、业务事件、业务行为, 而值对象是不包含业务逻辑的.

比如在实体中我们给定了订单实体, 订单实体一般对应着地址, 我们可以讲地址是对订单的一种扩充, 所以地址为值对象.

实体和值对象举例

以注册用户和地址举例:

在电商购物这个上下文角度观察: 注册用户可以看作一个实体, 而对应的地址可以看作为一个值对象

而在地区统计系统上下文角度观察: 地址可以算作一个实体, 而注册用户是可以作为一个值对象存在的.

实体可修改,值对象不可修改,只可以整体替换。实体是实实在在的业务对象,值对象只是对对象的描述。值对象依附以实体,实体没了值对象也就没了。

聚合和聚合根

通过上面的理论, 我们划分出了 限界上下文, 划分了领域的边界.

而后我们又分析找出了 实体和值对象,

下一步我们将实体、值对象进行聚合, 完成限界上下文下的领域建模

聚合

实体和值对象是很基础的领域对象。实体一般对应业务对象,它具有业务属性和业务行为;而值对象主要是属性集合,对实体的状态和特征进行描述。但实体和值对象都只是个体化的对象,它们的行为表现出来的是个体的能力。

我们划分的实体对象之间大多都是存在联系的, 彼此协作完成一个复杂的业务系统, 这里就需要我们使用聚合(或成为组合实体对象).

聚合根

当我们需要将一些实体对象组合起来完成限界上下文的领域建模时, 是需要将我们的实体对象规则控制、协调的, 这就是我们聚合根的作用了.

首先它作为实体本身,拥有实体的属性和业务行为,实现自身的业务逻辑。其次它作为聚合的管理者,在聚合内部负责协调实体和值对象按照固定的业务规则协同完成共同的业务逻辑。

以电商里面的订单举例

  1. 订单在聚合里是聚合根,与订单关联的有订单明细和收货地址。
  2. 订单明细包括商品ID,商品名称,价格以及数量等信息,由于订单明细是多个,它是一个集合,它被设计为实体,被订单引用。
  3. 而订单只有一个收货地址,这个收货地址的值来源于你个人中心维护的收货地址,收货地址只能被整体替换,所以它被设计为值对象。

关系图例

  1. 一套业务领域划分多个限界上下文子域
  2. 一个限界上下文子域对应多个聚合
  3. 一个聚合里面划分进多个实体和值对象, 并实现一个聚合根
  4. 一个聚合根调度多个实体、值对象

结语

本文主要为概念性说明, 借鉴于《DDD实战课》

更多精彩关注: