DDD领域驱动设计是现在非常火热的架构设计,下面我详解DDD领域驱动设计@mikechen
DDD
DDD(Domain-Driven Design,领域驱动设计)是一种以业务领域为中心的软件设计方法。

强调先理解业务,再用模型去表达业务,而不是先从数据库表/或技术框架出发 。
DDD 的核心价值:应对复杂性:将大问题拆解为多个小而清晰的“领域子问题”。
提升可维护性:业务变化时,只需调整对应限界上下文内的模型。
促进团队协作:开发、产品、业务专家使用同一套语言。
为微服务架构提供科学拆分依据(一个限界上下文 ≈ 一个微服务)。
DDD领域驱动设计
DDD 常见的分层是四层架构:用户接口层、应用层、领域层、基础设施层 。
如下图所示:

其中,用户接口层负责接收请求。
应用层,负责编排流程。
领域层,承载核心业务规则。
基础设施层,负责数据库、消息、缓存、外部服务等技术实现 。
可以把它理解为:
接口层:负责“怎么进来”,如 Controller、RPC 接口、命令行入口 。
应用层:负责“做什么流程”,比如下单、支付、退款的步骤编排,但不写复杂业务规则 。
领域层:负责“业务本身怎么运作”,这是 DDD 的核心 。
基础设施层:负责“技术细节怎么落地”,如持久化、消息队列、缓存、第三方 API 。
DDD核心设计
DDD 的核心可以概括成四个关键词:边界、模型、语言、聚合 。

领域模型
领域,就是系统所要解决的业务范围,里面包含实体、值对象、聚合、领域服务、领域事件等 。
例如,一个电商系统,它的“领域”不是“数据库”或“订单表”,而是:
商品;
订单;
支付;
库存;
物流;
这些共同组成了“电商领域”。
子域
一个大的业务领域,会继续拆成多个子域。

DDD通常把子域分成3类:
| 类型 | 含义 | 例子 |
|---|---|---|
| 核心域 | 企业最核心竞争力 | 推荐算法、交易系统 |
| 支撑域 | 支撑核心域运转 | 权限、消息、审核 |
| 通用域 | 大家都差不多 | 登录、短信、邮件 |
例如电商系统:
核心域:订单、支付
支撑域:库存、物流
通用域:用户登录、短信通知
限界上下文(Bounded Context)
这是DDD里最重要、最容易面试问到的概念。

同一个名词,在不同系统里,含义可能完全不同。
例如:
订单在不同系统中的含义:
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
因此:
物流订单;
财务订单;
其实是 三个不同模型,这就是,“限界上下文”。
边界是战略设计的起点,没有边界就没有清晰的模型。
通用语言
统一语言是团队内部共同使用的一套业务语言,开发、产品、测试、业务专家都尽量用同一套词汇交流 。
这样做的目的,是避免“业务说 A,代码写 B”的翻译损耗 。

例如:
错误写法:
产品说:冻结库存
开发说:update stock_status = 2
测试说:库存锁
大家理解都不一样。
DDD要求统一成:
“锁定库存(Lock Inventory)”
这样:
文档这么写
代码这么命名
接口也这么定义
实体(Entity)
实体,就是“有身份”的对象。
它最重要的特征,不是属性,而是“ID”。

例如:
用户 User
订单 Order
商品 Product
即使订单金额变了、地址变了,它仍然是同一个订单,因为它的 orderId 没变。
实体特点:
有唯一标识 ID;
生命周期长;
属性可以变化;
例如:
Order:
- orderId = 1001
- status = PAID
- amount = 99
后面状态变成已发货,它仍然还是同一个 Order。
值对象(Value Object)
值对象没有ID,它只关心“值”。

例如:
金额 Money;
地址 Address;
时间范围 DateRange;
实体 vs 值对象
| 对比 | 实体 | 值对象 |
|---|---|---|
| 是否有ID | 有 | 没有 |
| 是否可变 | 可变 | 通常不可变 |
| 比较方式 | 比较ID | 比较值 |
例如:
Address("上海", "浦东")
两个地址只要值一样,就是同一个地址,不需要ID。
聚合(Aggregate)
聚合是DDD里最重要的设计单位。
聚合 = 一组相关对象 + 一致性边界
例如订单系统:
Order
├─ OrderItem
├─ PaymentInfo
└─ DeliveryInfo
这些对象共同组成一个“订单聚合”。