✦ 什么是 DDD 架构?
在软件项目规模不断扩张的今天,传统分层架构(Controller → Service → DAO)常常随着业务复杂度提升而迅速失控:服务方法越来越多、类名难以表达业务意图、跨模块依赖混乱、业务逻辑掺杂技术细节,最终导致系统难以维护。
**DDD(领域驱动设计)**正是为解决复杂业务系统而生的一套架构思想。它主张:
让软件设计从业务领域出发,而不是从技术框架出发。
DDD 的核心不是过度追求技术炫技,而是通过合理划分领域、抽象领域模型、聚合业务语义,构建与业务共演化的软件架构。
✦ 为什么需要 DDD?
普通架构痛点:
| 问题 | 传统架构表现 |
|---|---|
| 职责不清晰 | Service 变成“上帝类”,方法一大堆 |
| 业务不可演化 | 改一个逻辑牵一发动全身 |
| 技术绑架业务 | 代码围着 ORM/Tables 转,而不是围着业务能力转 |
| 沟通成本高 | 业务人员说业务,程序员说表结构,沟通困难 |
DDD 优势:
✔ 聚焦业务价值
✔ 用统一语言建模业务
✔ 代码结构与业务架构一致
✔ 业务逻辑沉淀进模型,可复用可演化
✔ 面向领域能力,而不是面向 CRUD
✦ DDD 的核心概念
DDD 有四个重要对象:
1)实体(Entity)
有唯一标识的业务对象
如:用户、订单、资产
2)值对象(Value Object)
没有标识,仅以值区分
如:金额、坐标、MAC 地址、端口组合
3)聚合(Aggregate)
强一致性边界,将相关业务数据组合在一起
如:订单 + 订单项 → 一个聚合
4)领域服务(Domain Service)
无法归属到实体本身,但属于业务逻辑
例:订单付款、资产自动发现、策略匹配
✦ DDD 的分层结构
典型 DDD 分四层:
┌───────────────────────┐
│ Interface 层 │ (API / Controller)
└──────────┬────────────┘
│
┌──────────▼────────────┐
│ Application 应用层 │ 负责编排业务流程,不包含业务逻辑
└──────────┬────────────┘
│
┌──────────▼────────────┐
│ Domain 领域层 │ 业务核心:实体、聚合、领域服务
└──────────┬────────────┘
│
┌──────────▼────────────┐
│ Infrastructure 基础层 │ 数据库、缓存、第三方适配
└───────────────────────┘
普通 CRUD 是技术驱动,DDD 是业务驱动。
✦ 示例:资产管理的一项业务流程
业务需求:新增资产,若端口开放则进行协议识别并生成监控策略。
在传统架构下:
AssetService.Add() 方法 2000 行
IF端口判断 → 查数据库 → Ping → 调策略 → 写日志
改一次逻辑必然牵扯多个文件
在 DDD 下:
领域层:
Asset 聚合根:资产状态 / 端口集合 / 网络属性
Domain Service:ProtocolService.MatchStrategy()
应用层:
AddAssetUseCase 调度流程
基础设施:
AssetRepo 持久化
业务可表达、逻辑可测试、代码可演进。
✦ DDD 实施建议
| 阶段 | 建议 |
|---|---|
| 初期 | 不必一开始就全量上,先从复杂业务开始建模 |
| 落地 | 先统一语言(Ubiquitous Language),避免 IT 与业务话术不一致 |
| 增量演进 | 业务能力稳定后再拆聚合、划领域边界 |
| 技术点 | CQRS、事件驱动、策略模式能很好辅助 DDD 落地 |
✦ 什么时候适合用 DDD?
| 场景 | 是否推荐 |
|---|---|
| 业务简单、CRUD 为主 | ❌ 没必要 |
| 核心业务复杂、规则多变 | ✔ 强烈推荐 |
| 多团队协作、多领域边界 | ✔ DDD 的价值最大 |
| 原型验证、快速 MVP | ❌ 优先速度而不是架构 |
DDD 的目标不是复杂化架构,而是保护核心业务资产。
✦ 总结
DDD 不是写代码的一种方式,而是理解业务的一种方法。
当你的系统在成长,当业务复杂到无法靠增删改查继续支撑时,DDD 就不是选项,而是必然。
架构不是一开始就要做对,而是要让系统能持续做对。