当系统越来越复杂,你会发现:
- Service 方法越来越多,逻辑交叉混乱
- 数据表和业务逻辑绑在一起,改动一次牵一发动全身
- 开发、测试、业务沟通成本越来越高
这时候,仅靠 CRUD 或传统分层架构已经无法支撑业务增长。
DDD(Domain-Driven Design,领域驱动设计)正是为解决这种复杂业务而生的一套方法论。
第一部分:DDD 的核心思想
DDD 的核心目标:
让软件的结构与业务逻辑保持一致,让开发人员和业务人员讲同一套语言。
核心理念包括:
-
领域(Domain)
- 系统要处理的业务范围。
- 示例:在资产管理系统中,领域可以是“资产管理”、“策略匹配”、“告警通知”。
-
限界上下文(Bounded Context)
- 每个上下文内部术语、模型一致,但上下文之间可以重复定义同一概念。
- 示例:资产管理上下文中的“资产”,与用户管理上下文中的“资产”可能含义不同。
-
统一语言(Ubiquitous Language)
- 团队(开发 + 测试 + 业务)使用统一的语言描述业务。
- 示例:所有文档、代码、接口中,“资产策略匹配”都用同一术语。
第二部分:DDD 的战术模式
DDD 不只是概念,还提供具体建模手段:
| 模式 | 作用 | 示例 |
|---|---|---|
| 实体(Entity) | 有唯一标识的业务对象 | 资产、订单、用户 |
| 值对象(Value Object) | 没有唯一标识,按属性值判断相等 | 金额、坐标、端口信息 |
| 聚合(Aggregate) | 事务一致性边界,聚合内部保证规则 | 订单聚合 = 订单 + 订单明细 |
| 聚合根(Aggregate Root) | 聚合的唯一入口,外部只能通过它操作聚合 | 订单根对象控制订单明细的增删改 |
| 领域服务(Domain Service) | 无法归属实体的业务逻辑 | 资产策略匹配、支付计算 |
| 仓储(Repository) | 持久化聚合对象 | AssetRepository、OrderRepository |
| 领域事件(Domain Event) | 聚合内部状态变化,可被外部订阅 | 订单支付成功事件 → 触发库存扣减 |
第三部分:DDD 的落地原则
-
聚焦核心业务
- 不必为 CRUD 小功能使用 DDD。
- 优先为核心领域建模,让业务逻辑清晰可演化。
-
分层清晰
┌───────────── Interface ─────────────┐ │ Controller / API │ └─────────────▲─────────────┘ │ ┌─────────────▼─────────────┐ │ Application / UseCase │ │ 编排业务流程 │ └─────────────▲─────────────┘ │ ┌─────────────▼─────────────┐ │ Domain │ │ 聚合、实体、领域服务、事件 │ └─────────────▲─────────────┘ │ ┌─────────────▼─────────────┐ │ Infrastructure │ │ 数据库、缓存、消息队列等 │ └───────────────────────────┘ -
代码与业务语言一致
- 所有类名、方法名、接口、事件都用统一语言。
- 让业务人员也能看懂代码意图,沟通成本降低。
-
逐步演进
- 不要把整个系统一次性改成 DDD。
- 从核心业务开始,逐步拆分聚合和上下文。
第四部分:DDD 的落地案例(资产管理)
假设我们要实现资产策略匹配功能:
- 聚合根:Asset(资产)
- 值对象:PortInfo(端口信息)、IPRange
- 领域服务:StrategyService → 根据资产状态和端口匹配策略
- 仓储:AssetRepository → 负责持久化资产聚合
- 领域事件:AssetDiscovered → 当资产新上线时触发策略匹配
type Asset struct {
ID string
IP string
Ports []PortInfo
}
func (a *Asset) UpdatePorts(ports []PortInfo) {
a.Ports = ports
events.Publish(AssetDiscovered{AssetID: a.ID})
}
- 业务逻辑全部在聚合或领域服务中完成
- Controller 只做输入输出,Infrastructure 只做数据存取
- 团队对“资产上线 → 匹配策略 → 生成告警”流程有统一理解
第五部分:总结
DDD 的核心价值不在于复杂的建模术语,而在于让系统业务逻辑清晰、可演化、团队协作低成本。
- DDD 适合复杂业务核心
- 先聚焦核心领域,再逐步扩展
- 配合微服务、事件驱动、中台,才能支撑大型企业级系统