领域驱动设计(DDD)核心概念与落地实践
Executive Summary
核心观点(金字塔原理)
结论先行: DDD是应对复杂业务系统的有效方法论,通过统一语言、限界上下文划分和领域建模,将业务复杂度转化为可管理的技术架构;Axon框架提供了CQRS+Event Sourcing的工业级实现。
支撑论点:
- 战略设计:通过限界上下文(Bounded Context)划分子域,明确系统边界和团队职责
- 战术设计:使用聚合、实体、值对象、领域服务等构建块实现业务逻辑封装
- 技术落地:Axon框架提供命令处理、事件溯源、Saga编排等开箱即用能力
SWOT 分析
| 维度 | 分析 |
|---|---|
| S 优势 | 业务与技术对齐、边界清晰可演进、适合复杂业务场景 |
| W 劣势 | 学习曲线陡峭、前期建模成本高、不适合简单CRUD系统 |
| O 机会 | 微服务拆分指导、遗留系统重构、团队协作规范化 |
| T 威胁 | 过度设计风险、缺乏领域专家参与导致模型失真 |
适用场景
- 推荐使用:业务逻辑复杂、需要长期演进的核心系统
- 谨慎使用:简单CRUD、数据报表、技术驱动型项目
DDD 核心概念
战略设计(Strategic Design)
领域(Domain)
业务问题空间的整体范围,可分为:
- 核心域(Core Domain):业务核心竞争力所在
- 支撑域(Supporting Domain):辅助核心域的业务功能
- 通用域(Generic Domain):可复用的通用能力(如认证、通知)
限界上下文(Bounded Context)
- 领域模型的边界,在边界内保持模型的一致性
- 不同上下文可以有同名但含义不同的概念
- 是微服务拆分的重要参考依据
上下文映射(Context Map)
限界上下文之间的关系模式:
| 模式 | 说明 |
|---|---|
| 合作关系(Partnership) | 两个上下文团队共同协作 |
| 共享内核(Shared Kernel) | 共享部分模型和代码 |
| 客户-供应商(Customer-Supplier) | 下游依赖上游,上游需考虑下游需求 |
| 防腐层(Anti-Corruption Layer) | 隔离外部模型,防止污染本地模型 |
| 开放主机服务(Open Host Service) | 提供标准化协议供外部访问 |
| 发布语言(Published Language) | 定义通用交换格式 |
统一语言(Ubiquitous Language)
- 团队(开发、产品、领域专家)共同使用的术语
- 体现在代码、文档、沟通中
- 减少翻译损耗,确保业务意图准确传达
战术设计(Tactical Design)
实体(Entity)
- 具有唯一标识的领域对象
- 标识在整个生命周期内保持不变
- 示例:用户(User)、订单(Order)
值对象(Value Object)
- 无唯一标识,通过属性值判断相等性
- 不可变(Immutable)
- 示例:地址(Address)、金额(Money)
聚合(Aggregate)
- 一组相关对象的集合,作为数据修改的单元
- 聚合根(Aggregate Root)是外部访问的唯一入口
- 聚合内保证事务一致性,聚合间保证最终一致性
订单聚合示例:
┌─────────────────────────────┐
│ Order (聚合根) │
│ ├── OrderItem (实体) │
│ ├── OrderItem (实体) │
│ └── ShippingAddress (值对象)│
└─────────────────────────────┘
领域服务(Domain Service)
- 无法归属于单个实体的业务逻辑
- 无状态
- 示例:转账服务、定价策略
领域事件(Domain Event)
- 表示领域中发生的有意义的事件
- 命名使用过去时态:
OrderPlaced、PaymentReceived - 用于解耦和实现最终一致性
仓储(Repository)
- 聚合的持久化抽象
- 只为聚合根提供仓储
- 隐藏数据访问细节
工厂(Factory)
- 封装复杂对象的创建逻辑
- 保证创建的对象满足业务规则
CQRS 与 Event Sourcing
CQRS(命令查询职责分离)
┌─────────────┐
│ Client │
└──────┬──────┘
│
┌────────────┴────────────┐
│ │
▼ ▼
┌───────────┐ ┌───────────┐
│ Command │ │ Query │
│ Model │ │ Model │
└─────┘ └─────┬─────┘
│ │
▼ ▼
┌───────────┐ ┌───────────┐
│ Write DB │ ──事件──▶ │ Read DB │
└───────────┘ └───────────┘
优势:
- 读写模型独立优化
- 读模型可针对查询场景定制
- 支持多种读模型(缓存、搜索引擎等)
Event Sourcing(事件溯源)
- 不存储当前状态,存储状态变更事件序列
- 当前状态 = 初始状态 + 所有事件的回放
- 完整的审计日志,支持时间旅行调试
Axon Framework 实践
框架简介
Axon是实现DDD、CQRS、Event Sourcing的Java框架,提供:
- 命令处理(Command Handling)
- 事件存储与分发(Event Sourcing & Publishing)
- Saga编排(长事务协调)
- 分布式支持(Axon Server)
核心组件
| 组件 | 职责 |
|---|---|
| Command Gateway | 发送命令的入口 |
| Command Handler | 处理命令,修改聚合状态 |
| Event Store | 存储领域事件 |
| Event Handler | 处理事件,更新读模型 |
| Saga | 跨聚合的业务流程编排 |
快速开始
// 聚合根定义
@Aggregate
public class OrderAggregate {
@AggregateIdentifier
private String orderId;
private OrderStatus status;
@CommandHandler
public OrderAggregate(CreateOrderCommand cmd) {
// 验证业务规则
AggregateLifecycle.apply(new OrderCreatedEvent(cmd.getOrderId()));
}
@EventSourcingHandler
public void on(OrderCreatedEvent event) {
this.orderId = event.getOrderId();
this.status = OrderStatus.CREATED;
}
}
// 命令定义
@Value
public class CreateOrderCommand {
@TargetAggregateIdentifier
String orderId;
List<OrderItem> items;
}
// 事件定义
@Value
public class OrderCreatedEvent {
String orderId;
}
参考资源
DDD落地实践
- 美团DDD实践:https://mp.weixin.qq.com/s/R-jBnPhWJHs7J-4CETV88A
Axon Framework
- 官网:https://axoniq.io/
- DDD资源:https://axoniq.io/resources/domain-driven-design
- GitHub:https://github.com/AxonIQ
- 快速开始:https://github.com/AxonIQ/axon-quick-start
开源实践项目
- xtoon-boot(DDD脚手架):https://segmentfault.com/a/1190000039343707
推荐书籍
- 《领域驱动设计》Eric Evans
- 《实现领域驱动设计》Vaughn Vernon
- 《领域驱动设计精粹》Vaughn Vernon