DDD领域驱动设计详解(万字图文总结)

DDD领域驱动设计是现在非常火热的架构设计,下面我详解DDD领域驱动设计@mikechen

DDD

DDD(Domain-Driven Design,领域驱动设计)是一种以业务领域为中心的软件设计方法。

DDD领域驱动设计详解(万字图文总结)-mikechen

强调先理解业务,再用模型去表达业务,而不是先从数据库表/或技术框架出发 。

DDD 的核心价值:应对复杂性:将大问题拆解为多个小而清晰的“领域子问题”。

提升可维护性:业务变化时,只需调整对应限界上下文内的模型。

促进团队协作:开发、产品、业务专家使用同一套语言。

为微服务架构提供科学拆分依据(一个限界上下文 ≈ 一个微服务)。

 

DDD领域驱动设计

DDD 常见的分层是四层架构:用户接口层、应用层、领域层、基础设施层 。

如下图所示:

DDD领域驱动设计详解(万字图文总结)-mikechen

其中,用户接口层负责接收请求。

应用层,负责编排流程。

领域层,承载核心业务规则。

基础设施层,负责数据库、消息、缓存、外部服务等技术实现 。

可以把它理解为:

接口层:负责“怎么进来”,如 Controller、RPC 接口、命令行入口 。

应用层:负责“做什么流程”,比如下单、支付、退款的步骤编排,但不写复杂业务规则 。

领域层:负责“业务本身怎么运作”,这是 DDD 的核心 。

基础设施层:负责“技术细节怎么落地”,如持久化、消息队列、缓存、第三方 API 。

 

 

DDD核心设计
DDD 的核心可以概括成四个关键词:边界、模型、语言、聚合 。

DDD领域驱动设计详解(万字图文总结)-mikechen

领域模型

领域,就是系统所要解决的业务范围,里面包含实体、值对象、聚合、领域服务、领域事件等 。

例如,一个电商系统,它的“领域”不是“数据库”或“订单表”,而是:

商品;

订单;

支付;

库存;

物流;

这些共同组成了“电商领域”。

 

子域

一个大的业务领域,会继续拆成多个子域。

DDD领域驱动设计详解(万字图文总结)-mikechen

DDD通常把子域分成3类:

类型 含义 例子
核心域 企业最核心竞争力 推荐算法、交易系统
支撑域 支撑核心域运转 权限、消息、审核
通用域 大家都差不多 登录、短信、邮件

例如电商系统:

核心域:订单、支付

支撑域:库存、物流

通用域:用户登录、短信通知

 

限界上下文(Bounded Context)

这是DDD里最重要、最容易面试问到的概念。

DDD领域驱动设计详解(万字图文总结)-mikechen

同一个名词,在不同系统里,含义可能完全不同。

例如:

订单在不同系统中的含义:

系统
含义
交易系统
购买行为
物流系统
发货任务
财务系统
收款记录

因此:

交易订单;
物流订单;
财务订单;

其实是 三个不同模型,这就是,“限界上下文”。

边界是战略设计的起点,没有边界就没有清晰的模型。


 

通用语言

统一语言是团队内部共同使用的一套业务语言,开发、产品、测试、业务专家都尽量用同一套词汇交流 。

这样做的目的,是避免“业务说 A,代码写 B”的翻译损耗 。

DDD领域驱动设计详解(万字图文总结)-mikechen

例如:

错误写法:

产品说:冻结库存

开发说:update stock_status = 2

测试说:库存锁

大家理解都不一样。

DDD要求统一成:

“锁定库存(Lock Inventory)”

这样:

文档这么写

代码这么命名

接口也这么定义

 

实体(Entity)

实体,就是“有身份”的对象。

它最重要的特征,不是属性,而是“ID”。

DDD领域驱动设计详解(万字图文总结)-mikechen

例如:

用户 User

订单 Order

商品 Product

即使订单金额变了、地址变了,它仍然是同一个订单,因为它的 orderId 没变。


实体特点:

有唯一标识 ID;

生命周期长;

属性可以变化;

例如:

Order:
- orderId = 1001
- status = PAID
- amount = 99

后面状态变成已发货,它仍然还是同一个 Order。

 

值对象(Value Object)

值对象没有ID,它只关心“值”。

DDD领域驱动设计详解(万字图文总结)-mikechen

例如:

金额 Money;

地址 Address;

时间范围 DateRange;


实体 vs 值对象

对比 实体 值对象
是否有ID 没有
是否可变 可变 通常不可变
比较方式 比较ID 比较值

例如:

Address("上海", "浦东")

两个地址只要值一样,就是同一个地址,不需要ID。

 

聚合(Aggregate)

聚合是DDD里最重要的设计单位。

聚合 = 一组相关对象 + 一致性边界


例如订单系统:

Order
├─ OrderItem
├─ PaymentInfo
└─ DeliveryInfo

这些对象共同组成一个“订单聚合”。

评论交流
    说说你的看法