问题空间 vs 解决方案空间 = 业务划分 ≠ 代码划分
一、业务问题
DDD 战略设计中最常被混淆的:业务划分和代码划分不是一回事。
错误想法:
"业务有 3 个子域,代码就要分 3 个微服务"
正确理解:
- 业务划分 = 问题空间(Problem Space)= Subdomain
- 代码划分 = 解决方案空间(Solution Space)= Bounded Context
- 一个 Subdomain 可以对应多个 BC
- 一个 BC 可以对应多个 SubdomainVernon 在 Ch 2 明确区分这两个空间——这是 DDD 战略层的思维框架。
二、控制论视角
问题空间 = 业务需求
解决方案空间 = 技术实现
类比:
- 问题空间 = 控制目标(业务要什么)
- 解决方案空间 = 控制律(代码怎么实现)
关系:
- 一个目标可以多种实现
- 一个实现可以服务多个目标Vernon 原话:
"When we use the term 'domain', we must distinguish between problem space (business) and solution space (code)."
三、两个空间的本质
3.1 问题空间(Problem Space)
问题空间 = 业务是什么
- 子域(Subdomain)的划分
- 业务概念
- 不涉及具体技术
- "业务要做什么"
关键问题:
- 业务有哪几个子域?
- 哪个是核心?哪个是支撑?哪个是通用?
- 子域之间的关系是什么?3.2 解决方案空间(Solution Space)
解决方案空间 = 代码怎么组织
- 限界上下文(Bounded Context)的实现
- 实体、值对象、聚合
- 涉及具体技术(微服务/模块/包)
- "代码怎么写"
关键问题:
- 代码如何分模块?
- 哪些是一个 BC?
- BC 如何部署?
- BC 之间如何通信?3.3 两者的映射
关系(Vernon 强调):
- 1:1(最简单):
一个 Subdomain = 一个 BC
- 1:N(复杂子域拆 BC):
一个 Subdomain 拆成多个 BC
- N:1(多个 Subdomain 共享一个 BC):
多个简单子域共享一个 BC
不常见四、为什么混淆是危险的
混淆 1:业务划分 = 代码划分
- 业务有 N 个子域 → 强行做 N 个微服务
- 性能差、运维复杂
- "分布式单体"
混淆 2:解决方案影响问题空间
- 为了"代码整洁"强行拆 BC
- 破坏业务语义
正确理解:
- 业务划分是根本
- 代码划分服务业务
- 必要时可以违反 1:1 关系五、决策框架
5.1 何时 1:1
适用:
- 业务清晰
- 团队对齐
- 一个 BC 能容纳
- 不需要解耦5.2 何时 1:N(一个 Subdomain 拆 BC)
适用:
- Subdomain 太大
- 业务可独立演化
- 团队独立
- 部署独立
例:
"订单处理" 拆为:
- 订单创建 BC
- 订单查询 BC
- 订单管理 BC5.3 何时 N:1(多个 Subdomain 共享 BC)
适用:
- 多个子域都简单
- 共享基础设施
- 团队小
- 业务耦合
例:
"用户 + 权限" 共享一个 BC(都简单)六、工程实践
实战 1:识别你的问题空间
步骤:
1. 列出业务的所有活动
2. 划分成子域
3. 评估每个子域(Core/Supporting/Generic)
4. 画出子域关系图
5. 不涉及技术实战 2:识别你的解决方案空间
步骤:
1. 基于子域划分
2. 决定 1:1 / 1:N / N:1 映射
3. 决定每个 BC 的边界
4. 决定部署单元
5. 决定通信方式实战 3:避免"为技术而技术"
反模式:
- 业务有 3 个子域,但有 12 个微服务(过度拆分)
- 业务耦合紧密,但强行解耦(破坏业务)
正模式:
- 问题空间 = 业务划分(不变)
- 解决方案空间 = 代码划分(可变)
- 必要时为了性能/团队/演化,违反 1:1七、性能指标
| 指标 | 衡量 |
|---|---|
| 问题空间清晰度 | 子域划分是否清晰 |
| 解决方案清晰度 | BC 划分是否清晰 |
| 1:1 比例 | 多少 Subdomain-BC 是 1:1(应该高) |
| 拆分过度 | 多少不必要的拆分(应该低) |
八、边界判断
何时 1:1:
- 业务清晰
- 团队对齐
- 性能可接受
何时 1:N:
- Subdomain 太大
- 业务独立演化
- 团队独立
何时 N:1:
- 多个子域都简单
- 共享基础设施
- 团队小
九、与其他 L 层方法论的关系
| 方法论 | 关系 |
|---|---|
| bounded-context | 解决方案空间的核心 |
| subdomain | 问题空间的核心 |
| module-vs-bounded-context | Module 是 BC 的代码层 |
| context-map-relations | BC 关系 = 解决方案间集成 |
十、钱学森原话
Ch 21 §21.3(系统划分): "大系统的特点:不同的子系统有不同的目标……目标决定系统划分。"
Ch 6 §6.3(解耦): "只影响和它们相应的受控量"——BC 划分的根本目的。
十一、总结
问题空间 vs 解决方案空间 = 业务划分 ≠ 代码划分:
| 空间 | 概念 | 关键问题 |
|---|---|---|
| 问题空间 | Subdomain | 业务是什么 |
| 解决方案空间 | Bounded Context | 代码怎么组织 |
核心原则:
- 问题空间是根本(业务划分)
- 解决方案空间服务问题空间(代码划分服从业务)
- 1:1 是常态但非必须
- 避免技术驱动业务
一句话总结:问题空间决定"做什么",解决方案空间决定"怎么做",后者服务前者。