编程进阶网 编程进阶网
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • README
  • 面向对象设计

  • 常见设计原则

  • 巧学设计模式

  • 系统架构设计

    • README
    • 分层架构设计详解
    • 六边形架构设计
    • 命令查询职责分离
    • 事件驱动架构设计
    • 微服务拆分策略
    • 领域驱动战略设计
      • 1. 案例引入
        • 1.1 同名异义的混乱
        • 1.2 顺藤摸到根因
        • 1.3 我们要回答什么
      • 2. 架构概览
        • 2.1 战略设计五要素
        • 2.2 为什么这么切
      • 3. 统一语言基础
        • 3.1 语言即模型
        • 3.2 翻译损耗的代价
        • 3.3 沉淀语言的方法
        • 3.4 语言演化与守护
      • 4. 限界上下文识别
        • 4.1 上下文的本质
        • 4.2 同名异义识别法
        • 4.3 边界判定四标尺
        • 4.4 上下文与团队映射
      • 5. 子域分类与战略
        • 5.1 核心子域的识别
        • 5.2 支撑子域的取舍
        • 5.3 通用子域的复用
        • 5.4 投资决策矩阵
      • 6. 上下文映射九模式
        • 6.1 合作与共享内核
        • 6.2 客户供应商关系
        • 6.3 防腐层与开放主机
        • 6.4 发布语言与分离
      • 7. 战略到战术衔接
        • 7.1 上下文内的战术建模
        • 7.2 聚合根边界落地
        • 7.3 领域事件作为接口
        • 7.4 与六边形CQRS联动
      • 8. 战略反模式
        • 8.1 全公司统一模型
        • 8.2 上下文即微服务
        • 8.3 贫血战略文档
        • 8.4 模型与组织失配
        • 8.5 反模式五连击集锦
      • 9. 事件风暴实战
        • 9.1 三色便利贴法
        • 9.2 大图工作坊流程
        • 9.3 设计级事件风暴
        • 9.4 产出物与跟进
      • 10. 综合案例串讲
        • 10.1 案例真相揭晓
        • 10.2 一次战略落地全过程
        • 10.3 设计哲学回扣
        • 10.4 战略设计速查
    • 架构评审方法论
    • 架构演进实战指南
  • 编程
  • 系统架构设计
杨充
2022-03-15
目录

领域驱动战略设计

# 06.领域驱动战略设计

# 目录介绍

  • 1. 案例引入
    • 1.1 同名异义的混乱
    • 1.2 顺藤摸到根因
    • 1.3 我们要回答什么
  • 2. 架构概览
    • 2.1 战略设计五要素
    • 2.2 为什么这么切
  • 3. 统一语言基础
    • 3.1 语言即模型
    • 3.2 翻译损耗的代价
    • 3.3 沉淀语言的方法
    • 3.4 语言演化与守护
  • 4. 限界上下文识别
    • 4.1 上下文的本质
    • 4.2 同名异义识别法
    • 4.3 边界判定四标尺
    • 4.4 上下文与团队映射
  • 5. 子域分类与战略
    • 5.1 核心子域的识别
    • 5.2 支撑子域的取舍
    • 5.3 通用子域的复用
    • 5.4 投资决策矩阵
  • 6. 上下文映射九模式
    • 6.1 合作与共享内核
    • 6.2 客户供应商关系
    • 6.3 防腐层与开放主机
    • 6.4 发布语言与分离
  • 7. 战略到战术衔接
    • 7.1 上下文内的战术建模
    • 7.2 聚合根边界落地
    • 7.3 领域事件作为接口
    • 7.4 与六边形CQRS联动
  • 8. 战略反模式
    • 8.1 全公司统一模型
    • 8.2 上下文即微服务
    • 8.3 贫血战略文档
    • 8.4 模型与组织失配
  • 9. 事件风暴实战
    • 9.1 三色便利贴法
    • 9.2 大图工作坊流程
    • 9.3 设计级事件风暴
    • 9.4 产出物与跟进
  • 10. 综合案例串讲
    • 10.1 案例真相揭晓
    • 10.2 一次战略落地全过程
    • 10.3 设计哲学回扣
    • 10.4 战略设计速查

# 1. 案例引入

# 1.1 同名异义的混乱

先看一段真实事故。某中型 SaaS 公司,约 60 人技术团队,做的是面向中小企业的会员营销平台。系统跑了 3 年,业务跑通了,但每次跨团队开会都吵架——焦点全在一个词:「客户」。

场景:营销团队提需求:"给所有'高价值客户'发一张满 200 减 30 的券。"

开发反问:"'高价值客户'是指会员等级 ≥ V4 的吗?"

营销:"不是,是指最近 90 天消费 ≥ 5000 元的。"

CRM 团队插话:"等等,我们 CRM 里说的'高价值客户'是指 LTV(生命周期价值)大于 1 万的,跟你们都不一样。"

财务:"我这边'客户'是指开过发票的法人主体,自然人不算。"

客服:"我们工单里的'客户'是来电号码主人,连账号都不一定有……"

一个会开下来,「客户」这个词在五个团队嘴里指五种不同的东西。最后会议纪要是这么写的:"给高价值会员发券"——开发回去问产品:"你这'高价值'按谁的标准?" 产品说:"你们定吧。" 开发只好按"会员等级 ≥ V4"实现了——上线两天后被营销总监投诉,优惠券发错了人,CEO 拍桌子要追责。

继续往下挖,发现这并不是个例:

系统里到处都有「同名异义」与「异名同义」:
- "订单"在交易系统 = 包含商品和支付的复杂对象
- "订单"在物流系统 = 一个运单(含重量、目的地)
- "订单"在 CRM    = 一次成交记录(只有金额和时间)
- "用户"在登录系统 = 凭证(账号 + 密码)
- "用户"在会员系统 = 等级权益对象(含积分、生日、偏好)
- "买家"和"客户"和"会员"和"用户" —— 业务方分得清,系统里全混着叫
1
2
3
4
5
6
7

直觉怀疑:是不是字典/术语表没维护好?打开公司 Wiki 一看,确实有一份 2 年前写的「术语规范」,但已经没人维护,新概念全靠口耳相传——更糟的是,术语表写的「客户 = 注册过的用户」根本和五个团队任何一个都对不上。

# 1.2 顺藤摸到根因

带着这条线往下挖:

  • 假设 1:是不是产品文档不清楚?—— 翻开最新需求文档,写的就是"针对客户进行精准营销",业务方自己也没区分。
  • 假设 2:是不是开发命名水平差?—— 看代码,类名是 Customer、User、Member、Buyer 四个并存,每个都被多处使用且互相调用。
  • 假设 3:要不强制统一成一个 Customer 类?—— DBA 试过:把所有相关表合并成一张 customer 表,结果字段涨到 87 个,营销加字段必须协调登录团队上线,最后退回。
  • 假设 4:那要不每个团队完全用自己的概念?—— 也试过:交易出"订单",CRM 接到时不知道里面字段叫什么,集成全靠口头约定,接口出 bug 排查要 3 天。
  • 假设 5:根因到底在哪?——业务上"客户"在不同场景本来就是不同的东西,但系统把它们要么强行合并、要么完全割裂,没有"翻译规则"。

看似"命名问题"的事故,毛病不在词不在表,毛病在没有意识到——业务概念是有边界的,边界内统一、边界外翻译。这条不是 OOP 设计问题,是领域驱动战略设计的根问题。

这一段事故里至少藏着 7 个原理点:

① 为什么"全公司一个统一模型"行不通?              → 第 8.1 章
② 业务概念的边界怎么找? 凭什么说"这里是边界"?      → 第 4 章
③ 不同上下文里同名概念怎么共存又不打架?            → 第 6 章上下文映射
④ 哪些子域值得砸钱自研, 哪些买就行?              → 第 5 章
⑤ 业务方和开发为什么经常"说同一个词不是一回事"?     → 第 3 章统一语言
⑥ 战略画完了, 到代码层怎么落?                    → 第 7 章
⑦ 怎么把全公司业务模型一次理清?                   → 第 9 章事件风暴
1
2
3
4
5
6
7

# 1.3 我们要回答什么

这个事故就是本篇的主线案例。我们带着上面 7 个问号往下走,每讲完一章就解开一两个;最后在第 10 章把案例彻底剖开,并给出三种修复方案与各自的代价。

本篇路线:

战略设计五要素总图 (第 2 章)
   ↓
统一语言 (第 3 章) ─→ 解开"为什么业务和开发对不上"
   ↓
限界上下文 → 子域分类 (第 4-5 章) ─→ 解开"边界在哪、为什么"
   ↓
上下文映射 (第 6 章) ─→ 解开"跨边界如何协作"
   ↓
战略到战术 → 反模式 (第 7-8 章) ─→ 解开"如何落地与避坑"
   ↓
事件风暴实战 (第 9 章) ─→ 武器库
   ↓
综合案例 (第 10 章) ─→ 案例彻底剖开
1
2
3
4
5
6
7
8
9
10
11
12
13

📌 本篇定位:在系列中,本篇是承上启下的方法论核心。前面 02.六边形架构、03.CQRS、04.事件驱动、05.微服务拆分 都依赖"边界已经划好"这个前提;本篇就是讲这条边界从哪来。读完本篇后再看微服务/CQRS/事件驱动,能立刻回答:"这个边界凭什么这么划"。

# 2. 架构概览

# 2.1 战略设计五要素

DDD 战略设计是 Eric Evans 在 2003 年《领域驱动设计》一书中提出的一组思维工具,专门解决"业务复杂度如何拆解"。整套方法围绕五个核心要素:

┌─────────────────────────────────────────────────────────┐
│                  ① 领域 (Domain)                          │
│              一个组织在做的事情整体                          │
│              如:电商、保险、教育                            │
├─────────────────────────────────────────────────────────┤
│                  ② 子域 (Subdomain)                       │
│              领域内按业务能力的切分                          │
│         ┌────────┐ ┌────────┐ ┌────────┐                │
│         │核心子域│ │支撑子域│ │通用子域│                  │
│         │ 交易   │ │ 营销   │ │  认证  │                 │
│         └────────┘ └────────┘ └────────┘                │
├─────────────────────────────────────────────────────────┤
│              ③ 限界上下文 (Bounded Context)                │
│        模型边界 + 通用语言边界 + 团队边界 (三位一体)         │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐    │
│   │ 交易上下文   │  │ 营销上下文    │  │  会员上下文  │    │
│   │ Order/Item  │  │ Coupon/Rule │  │ Member/Lv   │    │
│   └─────────────┘  └─────────────┘  └─────────────┘    │
├─────────────────────────────────────────────────────────┤
│              ④ 通用语言 (Ubiquitous Language)              │
│         每个上下文内业务和开发共用的同一套词                  │
│         "订单"="交易上下文内的 Order 聚合"                  │
├─────────────────────────────────────────────────────────┤
│              ⑤ 上下文映射 (Context Map)                    │
│         上下文之间的协作关系图谱(9 种模式)                  │
│         交易 ──发布事件──→ 营销 (PL)                       │
│         交易 ──RPC──→ 会员 (ACL 防腐层)                    │
└─────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

五要素的核心属性速查:

要素 定义 关键属性 输出物
领域 公司在做的业务整体 唯一、不变 一句话使命
子域 按业务能力分块 分核心/支撑/通用三级 子域地图
限界上下文 模型边界 = 团队边界 内部语言一致,跨界要翻译 上下文列表
通用语言 业务-开发共识词典 上下文内唯一 术语表 + 代码命名
上下文映射 上下文协作关系 9 种模式可选 上下文映射图

# 2.2 为什么这么切

为什么 DDD 战略要分成"领域 → 子域 → 上下文 → 语言 → 映射"五层,而不是直接"画几个服务"完事?

疑惑:直接拿白板画几个框、连几条线,写明"这个服务负责什么",不就够了?为什么要五层概念?

论证:

  1. 概念错位是最贵的错误——代码 bug 几小时就能修,但模型错了,一年的代码全要推倒重来。先有清晰的领域思维,再写代码,是把"贵的错误"前置到便宜阶段。

  2. 业务复杂度天然是分层的——一个公司做的事(领域)天然由若干能力组成(子域),每种能力天然有自己的概念体系(上下文),每个上下文内业务和开发天然要说同一种话(语言),上下文之间天然要协作(映射)。五要素只是把这种天然结构显式化。

  3. 不同抽象层服务不同决策——

    • 领域层:决定"我们是谁、做什么"
    • 子域层:决定"哪些事自研、哪些买"
    • 上下文层:决定"团队怎么分、服务怎么拆"
    • 语言层:决定"代码里怎么命名"
    • 映射层:决定"跨团队接口如何协作"

    每一层错了,影响的决策范围不同——领域错了 = 战略错;上下文错了 = 组织错;语言错了 = 沟通错。

  4. 可演化才有意义——业务每年都在变,一次性"画死"的架构图三个月就过时。五要素是一套思考框架,让架构图能跟着业务变——子域可以重分类、上下文边界可以调整、语言可以演化。

  5. 反向验证——不用 DDD 战略的项目会怎样?参考第 1 章案例:业务方一个"客户"五种含义,开发胡乱建模,最后变成"数据库表为中心"的反向架构——表怎么设计代码怎么写,没人在乎业务语义,一年后系统僵化、bug 频出。

结论:DDD 战略设计的五要素,本质上是把"业务复杂度"的拆解过程标准化——领域定边界、子域定优先级、上下文定团队、语言定共识、映射定协作。这是面对中大型业务系统的思维上的根基哲学。

下面我们从最基础的"统一语言"开始,看它如何决定后续的一切。

# 3. 统一语言基础

# 3.1 语言即模型

疑惑:业务方说"客户"、开发写 User、产品文档写"会员"——只是用词不同而已,沟通时翻译一下不就行?

论证:试试看实际后果:

业务方:               开发翻译:             代码实现:
"高价值客户"     →    "VIP用户"     →    user.isVip()
"流失客户"      →    "30天没登录"   →    user.lastLoginAt < now-30d
"潜在客户"      →    "未注册访客"   →    没有 User 对象,存在 Visitor 表
1
2
3
4

三次"翻译"后,业务方再问:"给所有高价值客户发券" → 开发去找 user.isVip()——但业务说的"高价值"和代码里的"VIP" 早就不是一个东西了。VIP 标记半年前因为某次活动加上的,从此谁都不敢动;业务方说的"高价值"实际是近期消费额。两者重叠率不到 30%。

这就是翻译损耗——每翻译一次,就丢失一点语义;翻译三次,业务概念已经被磨损得面目全非。

结论:语言即模型,模型即代码。业务方说的词、产品文档写的词、代码里类名/方法名/字段名,必须是同一个词——这叫"统一语言(Ubiquitous Language)"。

❌ 翻译模型                    ✅ 统一语言
业务: 高价值客户                业务: 高价值客户
  ↓ 翻译                        ↓ 不翻译
产品: VIP                      产品: 高价值客户
  ↓ 翻译                        ↓ 不翻译
开发: User.isVip()             开发: Customer.isHighValue()
  ↓ 翻译                        ↓ 不翻译
DB:   user.vip_flag            DB:   customer.is_high_value
1
2
3
4
5
6
7
8

统一语言不是"开发去学业务术语"或"业务去学技术术语",而是业务和开发一起重新定义一套双方都用的词——往往这个过程就会暴露很多业务上的歧义("高价值"到底是什么意思?)。

# 3.2 翻译损耗的代价

翻译的代价是数量级递增的。一次需求评审到上线的完整链路:

业务方头脑里的概念          (信噪比 100%)
        │翻译 1
        ▼
口述需求 / 微信讨论          (信噪比 90%)
        │翻译 2
        ▼
PRD 文档                    (信噪比 80%)
        │翻译 3
        ▼
开发理解后的设计文档          (信噪比 65%)
        │翻译 4
        ▼
数据库表设计 + 类设计         (信噪比 50%)
        │翻译 5
        ▼
代码实现                    (信噪比 35%)
        │翻译 6(业务方上线后理解代码行为)
        ▼
业务方最终感知               (信噪比 20%)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

每次翻译损失 10~20% 的语义——六层下来只剩 1/5。这是大型项目"业务和开发永远在打架"的根因。

统一语言的本质就是砍掉中间所有翻译层:

业务方头脑里的概念
        │
        └─── (同一个词、同一个定义、同一个模型) ───┐
                                              │
                                              ▼
                              所有人(产品/开发/测试/运维/客服) 都用同一个词
                                              │
                                              ▼
                                         代码里也是同一个词
1
2
3
4
5
6
7
8
9

信噪比从 35% 拉回到 90%+。这就是 DDD 战略的第一红利。

# 3.3 沉淀语言的方法

"统一"不是嘴上说说,要有沉淀方法。三个落地动作:

方法 1 · 术语表(Glossary)

每个上下文一份术语表,业务和开发共同维护:

# 营销上下文术语表 v2.1(最后更新 2025-06-01)

## 客户类
- **高价值客户(High-Value Customer)**:最近 90 天累计消费 ≥ 5000 元的注册客户。
  - 同义词:(业务方常说)"大客户"、"重点客户" — 统一用"高价值客户"
  - 反义词:普通客户、潜在客户
  - 计算口径:以订单完成时间为准(不含取消单)
  - 代码:`Customer.isHighValue()`

## 优惠券类
- **满减券(Discount Voucher)**:达到指定消费门槛后立减固定金额的优惠凭证。
  - 不要混用:"折扣券"、"代金券"(折扣券指打折,代金券指无门槛)
  - 代码:`DiscountVoucher`
  - DB:`voucher`(type='DISCOUNT')
1
2
3
4
5
6
7
8
9
10
11
12
13
14

方法 2 · 代码即语言

代码里的类名、方法名、字段名、变量名必须与术语表完全一致,禁止译名变体:

// ❌ 名词不一致
class User {
  boolean isVip() { ... }              // 业务说"高价值客户"
}

// ✅ 与术语表一致
class Customer {
  boolean isHighValue() { ... }        // 业务用什么词,代码就用什么词
}
1
2
3
4
5
6
7
8
9

方法 3 · 文档即代码

PRD、设计文档、接口文档统一从术语表引用。写新文档时如果出现新词,先回去更新术语表——任何"自由发挥"的新词都视为债务。

# 3.4 语言演化与守护

语言是会变的——业务变化、概念精化都会让语言进化。守护三纪律:

纪律 1 · 增量更新,不要积压

新概念出现时立刻入表,不要等季度复盘批量更新——一周不更新,新词就开始流传变体。

纪律 2 · 谁提概念谁负责定义

业务方提的新需求里有新名词,评审时必须给定义——"你说的'活跃用户'是什么意思?"应作为评审环节的标准动作。

纪律 3 · 定期 review,删除过期词

每季度一次术语表 review,下线不再使用的旧词——保留只会让新人困惑。删除的词归档到"历史术语"。

红线:

红线 后果
业务方在群里说新词没人挑战 半年后变成跨团队歧义源
代码评审通过了非术语表里的命名 一年后变成无人能读的祖传代码
术语表更新不通知相关团队 同一个词两种解释 → 第 1 章案例重演
跨上下文偷用对方的术语 边界模糊 → 退化成"全公司统一模型"

统一语言不是一份文档,是一套日常约束——评审、命名、文档三处同时守,才能不退化。

# 4. 限界上下文识别

# 4.1 上下文的本质

疑惑:第 3 章说"上下文内统一"——这"上下文"到底是什么?怎么知道一段业务在哪个上下文?

论证:先看定义:

限界上下文(Bounded Context)= 一个模型 + 一套通用语言 + 一个团队 + 一组明确的边界

四位一体,缺一不可:

                  ┌──────────────────┐
                  │   限界上下文       │
                  │                  │
        模型边界  │  Customer        │  通用语言边界
       ┌─────────┤  Order           ├─────────┐
       │         │  Coupon          │         │
       │         │                  │         │
       │         └──────────────────┘         │
       │                                      │
       └─── 团队边界 ─── 部署边界 ─── 数据库边界 ─┘
1
2
3
4
5
6
7
8
9
10

为什么这四个边界天然重合?

  • 模型边界:在这个上下文里,"客户"指的是 X;出了边界,"客户"可能指 Y。模型形状不能跨越。
  • 通用语言边界:上下文内业务-开发说同一种话;跨边界要"翻译"。语言不能跨越。
  • 团队边界:模型由谁维护,语言由谁定义,只能由同一个团队负责——多团队同时改一个上下文 = 模型必然碎裂。
  • 部署/数据库边界:上下文是独立演进的单位——独立发布、独立扩容、独立数据存储(参见第 7 章03.CQRS 一库一服务原则)。

典型电商的上下文划分:

┌─────────────────────────────────────────────────────────┐
│  核心子域                                                │
│  ┌───────────────┐  ┌───────────────┐                  │
│  │ 交易上下文     │  │ 商品上下文      │                  │
│  │ Order/Payment │  │ Product/SKU   │                  │
│  └───────────────┘  └───────────────┘                  │
├─────────────────────────────────────────────────────────┤
│  支撑子域                                                │
│  ┌───────────────┐  ┌───────────────┐  ┌─────────────┐ │
│  │ 营销上下文      │  │ 会员上下文      │  │ 物流上下文   │ │
│  │ Coupon/Promo  │  │ Member/Level  │  │ Shipment    │ │
│  └───────────────┘  └───────────────┘  └─────────────┘ │
├─────────────────────────────────────────────────────────┤
│  通用子域                                                │
│  ┌───────────────┐  ┌───────────────┐  ┌─────────────┐ │
│  │ 认证上下文      │  │ 通知上下文      │  │ 支付上下文   │ │
│  │ Account/Token │  │ SMS/Email     │  │ 三方对接     │ │
│  └───────────────┘  └───────────────┘  └─────────────┘ │
└─────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

第 1 章案例中的"客户"在不同上下文里是不同的东西:

上下文 "客户" 的含义 关键属性
认证上下文 Account(账号凭证) account、password、token
会员上下文 Member(会员档案) level、points、joinDate
营销上下文 Customer(营销对象) tags、rfm、segments
交易上下文 Buyer(买家) shippingAddress、paymentMethod
客服上下文 Complainant(投诉人) contact、ticketHistory

这五个"客户"本质上不是同一个东西——只是恰好都用了"客户"这两个字。强行合并就是第 1 章 87 字段大表的悲剧。

# 4.2 同名异义识别法

如何系统化识别上下文边界?同名异义识别法是最直接的工具。

操作步骤:

第 1 步:把全公司所有名词列出来
        - 来源:业务文档、代码、Wiki、需求文档、表名
        - 用便利贴或表格
        - 不去重

第 2 步:找"同名"的词
        - 相同的词出现在多个地方
        - 标红:高频疑似同名异义词

第 3 步:逐个询问"在不同地方含义一样吗"
        - 一样 → 这是真的同义概念
        - 不一样 → 这是上下文边界信号

第 4 步:把"不一样"的概念按"业务场景"聚类
        - 同场景的概念聚在一起 → 一个上下文的候选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

第 1 章案例的实操:

词 出现场景 含义 是否同义
客户 登录 账号凭证 ❌ 不同义
客户 会员 等级权益对象 ❌ 不同义
客户 营销 标签分群对象 ❌ 不同义
客户 交易 买家 ❌ 不同义
客户 财务 法人主体 ❌ 不同义
客户 客服 投诉人 ❌ 不同义

5 处出现 5 种含义 → 强信号:这 5 处对应 5 个上下文。

异名同义反向识别:

词 实际场景 是否同义
买家 / 用户 / 客户 都指"下单的人"在交易里 ✅ 同义 → 应该选一个标准词
优惠券 / 代金券 / 折扣码 业务方混着叫 ⚠️ 需要业务方明确是不是同一回事

# 4.3 边界判定四标尺

光靠"同名异义"不够,需要更系统的判定标准。边界判定四标尺:

标尺 边界信号(应该拆) 合并信号(应该合)
语言 同一个词,含义不同 词汇高度重叠
规则 业务规则完全不同(如"下架"逻辑) 规则共享
生命周期 数据创建/变更/销毁的时机不同 同生共死
团队 不同团队的核心需求 同一团队主导

四标尺打分法:

对任意两个候选概念(如"商品"和"库存")打分:
- 语言相同?(0 = 完全不同 / 5 = 完全相同)
- 规则相同?(0~5)
- 生命周期相同?(0~5)
- 团队相同?(0~5)

总分 ≥ 15 → 强烈建议同上下文
总分 10~14 → 中等耦合,看具体场景
总分 ≤ 9 → 应该是不同上下文
1
2
3
4
5
6
7
8
9

举例:

"商品" vs "库存":
  - 语言:商品维度(SPU/SKU)vs 库存维度(仓位/批次)  → 2
  - 规则:商品上下架 vs 库存盘点  → 1
  - 生命周期:商品长期存在 vs 库存频繁变动  → 1
  - 团队:商品运营 vs 仓储  → 1
  总分 5 → 不同上下文(商品上下文 + 库存上下文)

"订单" vs "支付":
  - 语言:订单/支付订单术语接近  → 4
  - 规则:下单和支付几乎是同一业务流程  → 4
  - 生命周期:订单创建→支付→完成强耦合  → 5
  - 团队:交易团队同时管  → 5
  总分 18 → 同上下文(交易上下文)
1
2
3
4
5
6
7
8
9
10
11
12
13

# 4.4 上下文与团队映射

康威定律的反向应用:

系统设计反映组织结构 → 组织结构必须与上下文对齐。

上下文 ↔ 团队的对应原则:

✅ 1对1:一个上下文 = 一个团队
   优点:边界清晰,决策快
   适用:成熟的核心/支撑上下文

⚠️ N对1:一个团队管多个上下文
   适用:团队规模允许,且上下文相对简单
   风险:团队精力分散,可能照顾不过来

❌ 1对N:一个上下文由多个团队共同维护
   后果:模型必然碎裂、语言必然分裂
   除非:两团队是临时共建关系,且约定 6 个月内归并
1
2
3
4
5
6
7
8
9
10
11

第 1 章案例的组织反映:

原状(错位):                       目标(对齐):
                                                ┌─ 交易团队 ─ 交易上下文
后端组(20人) ── 维护所有"客户" ──┐    后端组拆分 ─┼─ 营销团队 ─ 营销上下文
                              │                 ├─ 会员团队 ─ 会员上下文
                              │                 └─ 平台团队 ─ 认证/通知
营销组、CRM组、客服组各自        │
对"客户"提需求,后端选一种实现    │    每个团队完全负责自己的上下文,
                              │    对外通过明确契约协作
                              ▼
                          歧义爆炸
1
2
3
4
5
6
7
8
9
10

实操判定:

  • 如果一个团队同时被 3 个以上业务方"提需求"——大概率上下文没划清
  • 如果一个上下文要找 3 个以上团队"会签"才能改——大概率边界不在团队上
  • 如果一个团队的人在内部分成几个小组各管一摊——可能上下文太大该拆

# 5. 子域分类与战略

# 5.1 核心子域的识别

疑惑:识别完上下文,每个都同等重要吗?应该平均投入资源吗?

论证:绝对不平均。子域分三级,投入策略完全不同:

                  战略价值
                     ▲
                     │
              核心子域  ★★★★★ ── 公司差异化竞争力
                     │
              支撑子域  ★★★    ── 业务必须但不差异化
                     │
              通用子域  ★      ── 行业通用、可外购
                     │
                     └─────────────► 投入策略
                                   核心:重金自研
                                   支撑:适度投入
                                   通用:买/外包
1
2
3
4
5
6
7
8
9
10
11
12
13

核心子域识别四问:

  1. 如果它不存在公司还是公司吗?→ 是 → 候选核心子域
  2. 它是公司比竞争对手强的地方吗?→ 是 → 候选核心子域
  3. 它是 CEO 在投资人面前讲的核心故事吗?→ 是 → 候选核心子域
  4. 行业里有标准产品可以买吗?→ 没有 → 候选核心子域

四问全 ✓,几乎确定是核心子域。

典型例子:

公司 核心子域 理由
淘宝 商品搜索、推荐 千人千面是平台核心竞争力
美团 订单调度、骑手路径 配送效率决定生死
字节 推荐算法 算法即护城河
银行 风控、信贷模型 风险定价是核心能力
第 1 章案例 SaaS 营销精准触达、自动化运营 这就是产品卖点

# 5.2 支撑子域的取舍

支撑子域:业务必须有,但不直接产生差异化竞争力——做得好不会让公司更强,但做不好会让公司挂掉。

典型例子:

子域 为什么是支撑而非核心
会员等级体系 行业有标准玩法,差异不大
营销活动后台 工具属性,配置型
订单履约状态机 流程标准,无算法
报表分析 内部使用,不对外卖
客服工单 标准 SaaS 能覆盖

投入策略:

支撑子域的三个选择:

A. 适度自研 (推荐)
   - 资深团队搭骨架,普通团队维护
   - 用成熟开源框架/组件
   - 不追求极致性能/体验
   - 投入:核心子域的 30~50%

B. 买现成 + 二开
   - 找成熟 SaaS(如 Salesforce CRM)
   - 自己写适配层、做必要二开
   - 投入低,启动快
   - 但有锁定风险

C. 完全外包
   - 适合一次性建设、后续不大改的
   - 注意外包合同里"代码所有权"条款
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

红线:绝不把支撑子域当核心子域投入——把"会员等级"做成自研 RPA 平台 = 浪费三年人力。

# 5.3 通用子域的复用

通用子域:全行业通用,不投入也得有——身份认证、消息推送、文件存储、支付通道。

典型例子与建议方案:

通用子域 推荐方案
用户登录认证 用 OAuth2 / OIDC 标准协议 + 开源/云服务(如 Keycloak、Auth0)
短信发送 用云服务(阿里云/腾讯云 SMS)
邮件发送 用 SendGrid / 阿里云邮件推送
对象存储 用 OSS / S3 / COS
支付通道 用支付宝 / 微信支付 / Stripe
地图服务 用高德 / 百度 / Google Maps
实时通信 用声网 / 即构 / Twilio

核心纪律:通用子域绝不自研——你不可能比阿里云做出更好的短信通道,也不应该花团队精力去做。

例外情况:

什么时候通用子域要"自研"?
- 业务量大到买不起 (如日发短信千万级,自建可能省钱)
- 有合规/数据主权要求 (如金融机构自建支付通道)
- 该子域恰好是公司核心 (如阿里云本身就是做云服务的)
1
2
3
4

# 5.4 投资决策矩阵

子域投资矩阵——把战略价值和实现难度交叉,给出投资决策:

                  实现难度
                  低              高
              ┌────────────┬────────────┐
              │            │            │
        高    │  快速建    │  集中力量   │
              │   (买/简)   │   (自研)    │
   战略       │            │            │
   价值       ├────────────┼────────────┤
              │            │            │
        低    │  最小可用   │  果断外包   │
              │  (开源凑)   │  (买现成)   │
              │            │            │
              └────────────┴────────────┘

→ 子域定位决定投资额,投资额决定团队配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

具体到投资额(中型公司参考):

子域类型 团队规模 年预算占比 技术债务容忍度
核心子域 团队总人力的 40~60% 50%+ 极低(重点重构)
支撑子域 30~40% 30% 中等
通用子域 5~10%(含运维) 20%(多数是采购费) 高(能跑就行)

第 1 章案例的诊断:

原状(错配):
- 70% 人力在做"会员等级体系"重写 → 这是支撑子域
- 20% 人力在做"自建短信网关" → 这是通用子域
- 10% 人力在做"营销精准触达" → 这才是核心子域

结果:
- 核心子域投入不足 → 营销效果差,客户流失
- 支撑子域过度投入 → 复杂度高、bug 多
- 通用子域自研 → 不如直接买阿里云便宜

修复:
- 营销精准触达 → 扩到 50%(核心子域应得)
- 会员等级 → 缩到 30%(用成熟模型即可)
- 短信网关 → 砍到 5%,迁阿里云 → 省 60% 成本
1
2
3
4
5
6
7
8
9
10
11
12
13
14

核心原则:资源永远稀缺,要砸在核心子域上。把核心子域当通用子域对待 = 自废武功;把通用子域当核心子域对待 = 资源浪费。两种错配都会让公司输给竞争对手。

# 6. 上下文映射九模式

# 6.1 合作与共享内核

疑惑:上下文划完了,但业务必须协作——A 上下文要用 B 上下文的数据,怎么办?

论证:DDD 总结了 9 种上下文映射模式,每种描述一种典型协作关系:

┌─────────────────────────────────────────────────────────┐
│                    9 种上下文映射模式                      │
├─────────────────────────────────────────────────────────┤
│  1. Partnership          合作关系                        │
│  2. Shared Kernel        共享内核                        │
│  3. Customer/Supplier    客户-供应商                      │
│  4. Conformist           追随者                          │
│  5. Anti-Corruption Layer 防腐层 (ACL) ★最常用             │
│  6. Open Host Service    开放主机服务 (OHS)               │
│  7. Published Language   发布语言 (PL)                    │
│  8. Separate Ways        分离方式                        │
│  9. Big Ball of Mud      大泥球 (反模式)                   │
└─────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13

模式 1 · Partnership(合作关系)

两个上下文深度绑定、协同开发——任何一方接口变更必须双方一起评审。

上下文 A  ◄═════════►  上下文 B
   │       共同演化      │
   │       共同发布      │
   └───── 共担成败 ─────┘

适用:业务深度耦合,必须一起成功或一起失败的两个核心上下文
风险:耦合过紧,本质上是"两个上下文不该分开"
1
2
3
4
5
6
7

典型例子:电商的"商品上下文"和"价格上下文"——商品改规格往往要同步价格策略,反之亦然。

模式 2 · Shared Kernel(共享内核)

两个上下文共享一小段模型或代码——这部分由双方共同维护。

┌──────────────┐         ┌──────────────┐
│  上下文 A     │         │  上下文 B    │
│              │         │              │
│   ┌──────────┴──────┬──┘              │
│   │    共享内核      │                 │
│   │  Money/Currency │                 │
│   └──────────┬──────┘                 │
│              │         │              │
└──────────────┘         └──────────────┘

适用:极少数真正稳定的公共概念(如 Money、Address)
警告:内核只能放"语义级稳定"的小模型,绝不能放业务逻辑
1
2
3
4
5
6
7
8
9
10
11
12

红线:共享内核只能装结构稳定的值对象——Money、DateRange、Address。禁止放业务规则、聚合根、领域服务——一旦放进去就意味着两个上下文必须共同演进。

# 6.2 客户供应商关系

模式 3 · Customer/Supplier(客户-供应商)

下游是"客户",上游是"供应商"——下游需求能影响上游优先级。

上游 (供应商)              下游 (客户)
  会员上下文 ────────────►  营销上下文
                          │
                          │ "营销需要新字段:lastPurchaseDate"
                          ▼
   会员团队 ◄──── 排期满足 ── 营销团队

适用:内部团队之间,下游对上游有正式影响力的合作
要求:有明确的需求池、迭代节奏、SLA
1
2
3
4
5
6
7
8
9

关键特征:下游不是"被动接受",而是有发言权——上游会把下游需求纳入迭代规划。

模式 4 · Conformist(追随者)

下游完全适配上游模型,不反抗、不翻译。

上游 (强势)                下游 (弱势)
  外部支付系统 ────────────►  我方订单上下文
  (字段名 USR_NO/CST_ID)    (代码里也写 USR_NO/CST_ID)

适用:上游是外部系统、大厂、合作方,你无法影响它
代价:上游模型再丑,你也得用;上游字段语义变,你也跟着痛
1
2
3
4
5
6

何时选 Conformist:当 ACL 的翻译成本 > 模型不优雅的代价时——比如对接一个用一年就下线的合作方系统。

# 6.3 防腐层与开放主机

模式 5 · Anti-Corruption Layer(防腐层,ACL)⭐ 最常用

下游建一层翻译适配层,把上游模型转换成本上下文需要的模型。

本上下文 (干净)        ACL (翻译层)        外部上下文 (脏)
┌──────────────┐    ┌────────────┐      ┌───────────────────┐
│              │    │ Translator │      │  legacy_user.dat   │
│  Customer    │◄───┤ Adapter    │◄─────│   USR_NO          │
│   - id       │    │ Mapper     │      │   USR_NM_CN       │
│   - name     │    │            │      │   GRD_LV          │
│   - level    │    └────────────┘      │   RGSTR_DT        │
│              │       一层防腐墙          │   ...             │
└──────────────┘                         └───────────────────┘
   本侧模型简洁优雅                          外部模型奇葩难懂

红利:
- 外部模型再烂,本上下文不被污染
- 外部接口变更,只改 ACL 一个地方
- 本侧团队心智负担最小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

ACL 的实现:

// 本上下文的领域模型
class Customer {
    CustomerId id;
    String name;
    MemberLevel level;
}

// ACL 层(防腐层)
class LegacyUserAcl {
    private LegacyUserClient legacyClient;

    public Customer fetchCustomer(CustomerId id) {
        LegacyUserDTO raw = legacyClient.queryByUsrNo(id.value());
        // 翻译:奇葩字段 → 本侧领域语言
        return new Customer(
            new CustomerId(raw.getUSR_NO()),
            raw.getUSR_NM_CN(),
            mapLevel(raw.getGRD_LV())  // GRD_LV='A' → MemberLevel.PLATINUM
        );
    }

    private MemberLevel mapLevel(String legacyLevel) {
        return switch (legacyLevel) {
            case "A" -> MemberLevel.PLATINUM;
            case "B" -> MemberLevel.GOLD;
            default  -> MemberLevel.NORMAL;
        };
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

铁律:任何对接老旧系统、外部系统、第三方 API 的场景,默认建 ACL——成本永远比"侵入式适配"低。

模式 6 · Open Host Service(开放主机服务,OHS)

上游为多个下游提供一套稳定、标准化的开放接口。

            ┌─── 下游 A
上游 ──OHS──┼─── 下游 B
            ├─── 下游 C
            └─── 下游 D

要求:
- 接口契约明确(OpenAPI / gRPC Proto)
- 严格向后兼容
- 多版本并存
- 完善文档

适用:核心子域上游被多个下游消费(如订单服务被营销/履约/客服共同使用)
1
2
3
4
5
6
7
8
9
10
11
12

OHS vs Customer/Supplier:

  • C/S:下游数量少(1~2 个),可以为下游定制
  • OHS:下游数量多(5+),必须标准化、不定制

# 6.4 发布语言与分离

模式 7 · Published Language(发布语言,PL)

上下游之间约定标准化的协议/格式——独立于任何一方实现。

上下文 A ──┐                              ┌── 上下文 C
            │      Published Language    │
            ├─── (JSON Schema / IDL) ────┤
            │                            │
上下文 B ──┘                              └── 上下文 D

例子:
- 行业标准:HL7(医疗)、SWIFT(银行)、ISO20022(金融)
- 公司标准:自定义 Event Schema(如 OrderCreatedEvent v1.0)
- 通用标准:CloudEvents、OpenTelemetry
1
2
3
4
5
6
7
8
9
10

与 OHS 关系:OHS 是"开放接口",PL 是"接口使用的语言/格式"——常一起出现:上游提供 OHS,OHS 用 PL 描述。

模式 8 · Separate Ways(分离方式)

两个上下文完全不集成——各做各的,没有任何接口往来。

上下文 A          上下文 B
   │                │
   │  (无任何关系)    │
   │                │

适用:集成成本 > 收益时
例子:
- HR 系统 vs 营销系统:业务上几乎无关
- 内部工具 vs 客户产品:客户根本看不到内部
1
2
3
4
5
6
7
8
9

警惕:Separate Ways 不是"忘了集成",是"主动选择不集成"——必须明确写在上下文映射图上,否则未来会有人"补一个 RPC"。

模式 9 · Big Ball of Mud(大泥球)⚠️ 反模式

上下文边界混乱、互相耦合、谁也说不清谁调谁。

A ─→ B ─→ C
↑ ↘ ↙ ↘ ↗ │
│ ╳   ╳   │
↓ ↗ ↘ ↗ ↘ ↓
D ←─ E ←─ F

特征:
- 修改任何一处影响多处
- 模型互相穿透,谁的代码都在谁里面
- 上下文形同虚设
1
2
3
4
5
6
7
8
9
10

修复方法:老老实实做边界手术——按本章方法重新画图,逐个建 ACL 隔离,分阶段切流。详见 05.微服务拆分策略 第 8 章。

九模式选型决策表:

场景 推荐模式
两个核心上下文,团队紧密协作 Partnership
共享极小段稳定模型 Shared Kernel(慎用)
内部上下游,下游有发言权 Customer/Supplier
对接强势外部系统 Conformist
对接老旧/外部/不稳定系统 ★ 防腐层 (ACL)
核心上游被多下游消费 OHS + PL
跨组织、跨公司协议 Published Language
业务上无关,强行集成无价值 Separate Ways
当前混乱状态,要重构 识别并重画为以上之一

# 7. 战略到战术衔接

# 7.1 上下文内的战术建模

战略设计画完了——领域、子域、上下文、语言、映射——下一步进入上下文内的战术建模。

战略设计 (本篇)              战术设计 (在面向对象专栏)
                              [实体/值对象/聚合/领域服务/资源库/事件]
  限界上下文                       │
       │                          │
       └─── 上下文内部 ────────────┘
            就是战术建模的舞台
1
2
3
4
5
6

每个限界上下文内部,独立做战术建模:

交易上下文                       会员上下文
┌─────────────────────────┐    ┌─────────────────────────┐
│ 聚合根: Order            │    │ 聚合根: Member           │
│   - OrderItem (实体)     │    │   - Level (值对象)        │
│   - Money (值对象)       │    │   - Points (值对象)       │
│ 领域服务: PriceCalculator│    │ 领域服务: LevelUpgrade   │
│ 资源库: OrderRepository  │    │ 资源库: MemberRepository │
│ 事件: OrderPlaced        │    │ 事件: LevelUpgraded     │
└─────────────────────────┘    └─────────────────────────┘
   战术建模在内部进行              战术建模在内部进行
   每个上下文独立                   每个上下文独立
1
2
3
4
5
6
7
8
9
10
11

核心纪律:战术建模严禁跨上下文——交易上下文 的 Order 永远不能直接持有 会员上下文 的 Member 对象引用,只能持有 BuyerId 这种 ID 值对象,需要 Member 详情时通过 ACL 或事件获取。

# 7.2 聚合根边界落地

聚合根(Aggregate Root) 是战术设计核心——但它的边界由战略设计决定。

战略层决定:
  - 哪些概念在同一上下文 (第 4 章四标尺)
  - 哪些是聚合根 (业务一致性边界)

战术层执行:
  - 聚合根作为事务边界
  - 聚合内强一致
  - 聚合间最终一致
1
2
3
4
5
6
7
8

举例:订单聚合

交易上下文:
┌────────────────────────────────────┐
│  Order (聚合根)                     │
│    - orderId                        │
│    - buyerId         ← ID 引用      │
│    - items: List<OrderItem>         │  ← 内部实体
│    - totalAmount: Money             │  ← 值对象
│    - status: OrderStatus            │
│                                     │
│    methods:                         │
│      - addItem(...)                 │
│      - pay(...)                     │
│      - cancel(...)                  │
└────────────────────────────────────┘
   ↑
   不直接持有 Buyer 对象
   不直接持有 Product 对象
   需要详情时通过 ACL/事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

为什么聚合内引用要用 ID?

❌ 直接持有对象引用
class Order {
    Buyer buyer;        // 持有跨上下文对象
    List<Product> products;
}
→ 加载 Order 必须加载 Buyer 和 Products
→ 跨上下文调用、级联加载、性能崩溃

✅ 用 ID 引用
class Order {
    BuyerId buyerId;
    List<ProductId> productIds;
}
→ Order 自给自足
→ 需要 Buyer 详情时显式调用
→ 边界清晰、性能可控
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

详细的聚合设计原则见 对象设计与建模。

# 7.3 领域事件作为接口

上下文之间最优的协作方式 = 领域事件。

交易上下文                     消息总线                    营销上下文
   │                            │                          │
   ├─ Order.pay()                │                          │
   ├─ 发布 OrderPaidEvent ──────►│                          │
   │   {orderId, buyerId,        │                          │
   │    amount, paidAt}          ├──────────────────────────►│
   │                             │     订阅 OrderPaidEvent   │
   │                             │                          ├─ 自动计算积分
   │                             │                          ├─ 检查满返活动
   │                             │                          └─ ...

红利:
- 交易上下文不需要知道营销存在(解耦)
- 营销可以独立增加新的业务规则(开放扩展)
- 事件即跨上下文契约(用 PL 语言描述)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

领域事件作为接口的优势:

维度 同步 RPC 领域事件
耦合度 A 必须知道 B 的存在 A 只需要发事件
性能 同步等待 异步处理
可用性 B 挂了 A 也卡 B 挂了不影响 A
扩展性 加 C 要改 A 加 C 只要订阅事件
一致性 强一致 最终一致

详细实现见 04.事件驱动架构设计。

# 7.4 与六边形CQRS联动

战略设计是起点,配合六边形/CQRS/事件驱动才能完整落地:

[06.DDD战略设计]  → 定义上下文边界、语言、映射
        │
        ▼
[02.六边形架构]   → 每个上下文内部,领域核心独立于框架
        │
        ▼
[03.CQRS]        → 重负载上下文内部,读写分离
        │
        ▼
[04.事件驱动]    → 上下文之间,用事件解耦
        │
        ▼
[05.微服务拆分]  → 把上下文物理拆成独立服务(如果需要)
1
2
3
4
5
6
7
8
9
10
11
12
13

完整落地图:

                 ┌───────── 业务方 ─────────┐
                 │                          │
                 │     通用语言 (第 3 章)      │
                 │                          │
                 └──────────┬───────────────┘
                            ▼
              ┌─────────────────────────────┐
              │ 上下文映射图 (第 6 章)         │
              │   交易 ──事件──→ 营销         │
              │   交易 ──ACL──→  外部支付      │
              └──────┬───────────┬──────────┘
                     ▼           ▼
        ┌─────────────────┐ ┌─────────────────┐
        │ 交易上下文        │ │ 营销上下文       │
        │ ┌─────────────┐  │ │ ┌─────────────┐ │
        │ │六边形架构    │  │ │ │六边形架构    │ │
        │ │ +CQRS       │  │ │ │  (轻 CQRS)  │ │
        │ │ +事件溯源    │  │ │ │             │ │
        │ └─────────────┘  │ │ └─────────────┘ │
        └─────────────────┘ └─────────────────┘
        独立服务 + 独立数据库    独立服务 + 独立数据库
        (微服务拆分,第 5 章)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 8. 战略反模式

# 8.1 全公司统一模型

最常见、最害人的反模式——追求"全公司只有一个 Customer / 一个 Order / 一个 User"。

❌ 反模式:统一大模型

           Customer (87个字段)
          ┌──────────────────┐
          │ id, name         │ ← 登录上下文用
          │ password         │ ← 登录上下文用
          │ level, points    │ ← 会员上下文用
          │ tags, rfm        │ ← 营销上下文用
          │ taxId, invoice   │ ← 财务上下文用
          │ contact, ticket  │ ← 客服上下文用
          │ ...87个字段       │
          └──────────────────┘
            ↑↑↑↑↑↑
          所有上下文共用
1
2
3
4
5
6
7
8
9
10
11
12
13
14

后果:

  1. 字段膨胀——每个团队都要加自己需要的字段,到 100+ 字段后查询性能崩溃
  2. 变更地狱——会员上下文加字段,登录、营销、财务全部要协调升级
  3. 权限失控——客服能看到所有字段,包括财务的发票信息
  4. 语义混乱——"isActive" 在登录上下文是"账号未冻结",在营销上下文是"30天内有交互",混在一个字段里说不清

修复:按上下文拆开,每个上下文一份自己的 Customer 模型:

✅ 上下文内独立模型

登录上下文.Account          营销上下文.Customer
- accountId               - customerId
- credential              - tags
- status                  - segments

会员上下文.Member           财务上下文.Payer
- memberId                - payerId
- level                   - taxId
- points                  - invoiceInfo

每个上下文 5~15 字段
通过 ACL 或事件互相协作
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 8.2 上下文即微服务

第二个常见误区——机械地"一个上下文一个微服务"。

❌ 误区
   上下文 A → 必须独立微服务 A
   上下文 B → 必须独立微服务 B
   上下文 C → 必须独立微服务 C
1
2
3
4

真相:上下文是逻辑边界,微服务是物理边界——不必一一对应。

合理对应方式:
- 模块化单体: 多个上下文 同一个进程,但内部强模块边界
- 单服务多上下文: 1 个微服务装 2~3 个紧密协作的上下文
- 单上下文多服务: 1 个超大上下文按读/写/批拆成多个服务 (CQRS)
- 上下文即微服务: 1:1 对应 (最常见)
1
2
3
4
5

何时合并多个上下文到一个服务:

  • 团队规模 < 30 人 → 全部上下文在一个模块化单体里
  • 上下文之间调用极频繁 → 合并为一个服务避免网络开销
  • 上下文还在快速演进,边界不稳 → 暂不物理拆分

何时把一个上下文拆成多个服务:

  • 读 QPS >> 写 QPS → 拆成读服务 + 写服务(CQRS)
  • 实时业务 + 批处理 → 拆成在线服务 + 批处理服务
  • 巨大上下文(> 30 万行代码)→ 内部再分子上下文

先有边界,再选物理形态——别本末倒置。详见 05.微服务拆分策略 第 6 章。

# 8.3 贫血战略文档

第三个反模式——画了一堆战略文档,但跟代码完全脱节。

❌ 贫血战略文档症状:
- Wiki 里有一份"领域模型图"——3 年前画的,没人维护
- 代码里类名/字段名与术语表完全对不上
- 新人入职先看文档,看完一脸懵——"代码里根本找不到这些概念"
- 业务方提需求时,产品再翻译一遍——退回"翻译损耗"
1
2
3
4
5

根因:战略设计被当成"文档工作"——开会画图、写 Wiki、然后归档。没有任何机制把文档同步到代码。

修复:

文档类型 同步机制
术语表 进入 Code Review 检查清单——命名不符合术语表 → reject
上下文映射图 与代码仓库映射,每个上下文 = 一个独立 repo / module
子域分类 进入项目立项模板——立项时必须标明属于哪个子域
领域事件 用 Schema Registry 管理,事件定义即接口契约

铁律:战略文档要么进入日常工作流,要么就别写——写了不维护,比不写还误导。

# 8.4 模型与组织失配

第四个反模式——画好了上下文模型,但组织结构没跟着调整。

❌ 失配场景:
   模型层划分了 5 个上下文
   组织层只有 2 个团队
   → 每个团队管 2~3 个上下文
   → 每个上下文有 1~2 个团队的人改
   → 半年后模型必然失控

   或反过来:
   模型层划分了 3 个上下文
   组织层有 8 个团队
   → 每个上下文 2~3 个团队抢着改
   → 互相冲突, 沟通成本爆炸
1
2
3
4
5
6
7
8
9
10
11
12

康威定律的双向作用:

正向: 组织结构 → 系统结构
     (你的团队怎么分,你的系统就长成什么样)

反向: 想要的系统结构 → 必须调整组织结构
     (想拆出独立上下文,必须先有独立团队)
1
2
3
4
5

修复决策:

当模型与组织失配时, 二选一:
A. 调整组织以适配模型 (理想,需要 VP 级支持)
B. 调整模型以适配组织 (现实,接受耦合的代价)

C. (最差) 维持失配,假装没事
   → 半年后必然回到第 1 章的混乱
1
2
3
4
5
6

实操建议:做战略设计之前先评估组织变更的可能性——如果组织铁打不动,就别画一个 5 上下文方案给 2 团队执行。

# 8.5 反模式五连击集锦

实战中最常踩的坑汇总:

反模式 1 · 全公司统一模型

❌ 一个 Customer 表 87 字段管所有
✅ 每个上下文独立 Customer 模型
1
2

反模式 2 · 上下文机械等于微服务

❌ 5 个上下文必须 5 个微服务
✅ 按团队规模 + 调用频率决定物理形态
1
2

反模式 3 · 战略文档不进代码

❌ Wiki 写一遍, 代码命名各写各的
✅ 术语表 = Code Review 红线
1
2

反模式 4 · 模型与组织失配

❌ 画 5 个上下文给 2 个团队
✅ 模型设计必须考虑组织实际
1
2

反模式 5 · 跨上下文共享聚合根

❌ Order 持有 Customer 对象引用
✅ Order 只持有 CustomerId, 需要详情走 ACL/事件
1
2

# 9. 事件风暴实战

# 9.1 三色便利贴法

事件风暴(Event Storming) 是识别上下文最有效的工具——Alberto Brandolini 2013 年提出,3 天工作坊 = 6 个月架构会议的效果。

核心物料:

┌─────────────────────────────────────────────────────────┐
│   材料清单                                                │
│   - 一面 4~6 米长的墙 (或长会议室白板)                       │
│   - 5 种颜色便利贴 (大量):                                  │
│        🟠 橙色 → 领域事件 (过去时,如"订单已支付")              │
│        🔵 蓝色 → 命令 (动词,如"提交订单")                     │
│        🟡 黄色 → 角色/参与者 (人或外部系统)                    │
│        🟣 紫色 → 业务策略/规则                                │
│        🔴 红色 → 问题/疑惑/争议点                             │
│   - 厚记号笔每人一支                                          │
│   - 全员到场: 产品/开发/测试/运营/客服/部分业务方              │
└─────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12

为什么这五种便利贴?

颜色 含义 作用
🟠 事件 "发生了什么" 业务关心的事实,最稳定
🔵 命令 "谁做了什么" 触发事件的动作
🟡 角色 "谁发起命令" 用户/外部系统
🟣 策略 "什么时候自动做什么" 业务规则/自动化
🔴 问题 "我不确定/不同意" 暴露歧义和盲区

核心思想:以事件为骨架建模——事件是业务的本质(发生了就发生了),命令/角色/策略都是为事件服务的。

# 9.2 大图工作坊流程

3 天工作坊的标准流程(Big Picture EventStorming):

Day 1: 发散
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
09:00 介绍方法、规则、目标
09:30 第 1 轮:所有人写事件 (橙色)
       - 不讨论、不评判,30 分钟猛写
       - 每人 30+ 张事件
       - 全部贴到墙上 (无序)

10:30 第 2 轮:按时间排序
       - 拉出一条时间轴
       - 把事件按发生顺序排
       - 删除重复、合并相似

12:00 午餐

14:00 第 3 轮:补充罕见事件
       - "异常路径"事件 (订单已取消、支付已失败)
       - "管理操作"事件 (商品已下架、客服已介入)

16:00 第 4 轮:标注热点
       - 红色便利贴贴在争议点
       - "这里到底什么时候触发?"
       - "这两个事件是同时还是先后?"

17:00 Day 1 收尾 — 墙上应有 200~500 张事件

Day 2: 收敛
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
09:00 第 5 轮: 找出"主流程"
       - 用粗线圈出主要业务流程
       - 一般是 3~5 条线 (下单流程、退款流程、客服流程...)

10:30 第 6 轮: 标注命令和角色
       - 蓝色: 每个事件前面贴上触发它的命令
       - 黄色: 每个命令前面贴上发起者

14:00 第 7 轮: 识别聚合
       - 命令+事件对作用在哪个对象上?
       - 用框圈出聚合 (Order/Product/Member...)

16:00 第 8 轮: 找上下文边界
       - 哪些聚合天然属于一组?
       - 在它们外面画大框 → 候选上下文

17:00 Day 2 收尾 — 墙上应有清晰的上下文边界

Day 3: 验证
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
09:00 第 9 轮: 走查每条主流程
       - 业务方逐一讲解
       - 开发挑战可行性
       - 红色问题逐一消除

14:00 第 10 轮: 标注上下文映射
       - 上下文之间的事件流向
       - 同步调用 vs 异步事件
       - 选择 9 模式之一

16:00 第 11 轮: 产出物拍照存档
       - 全墙拍照
       - 转录到数字工具 (Miro/draw.io)
       - 产生上下文映射图 + 术语表初稿
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

# 9.3 设计级事件风暴

大图风暴解决"上下文怎么划"——设计级风暴(Design-Level EventStorming) 进一步解决"上下文内部怎么建模"。

用法:选定一个上下文,单独再开一场 1~2 天小风暴,目的是产出战术建模物料。

聚焦在一个上下文 (如交易上下文)
        │
        ▼
重新展开事件流
        │
        ▼
为每个事件细化:
  - 命令携带的数据 (Command Payload)
  - 事件携带的数据 (Event Payload)
  - 触发命令所需的"前置条件" (绿色便利贴)
  - 命令的"输入数据" (粉色便利贴)
        │
        ▼
识别聚合根:
  - 谁是事件的发出者
  - 谁是命令的接收者
  - 一致性边界在哪
        │
        ▼
产出物:
  - 聚合根列表 + 字段
  - 命令-事件清单 (= 接口契约)
  - 业务策略清单 (= 领域服务)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

设计级 vs 大图级:

维度 大图级 设计级
范围 全公司业务 一个上下文
时长 2~3 天 1~2 天
参与者 全员 上下文相关团队
产出 上下文地图 聚合 + 命令 + 事件
后续 启动战略落地 直接开始战术编码

# 9.4 产出物与跟进

工作坊产出物清单与跟进机制:

产出物 1 · 事件风暴墙照片

归档到团队共享空间
转录到 Miro/draw.io (永久保存)
作为新人入职第一份资料
1
2
3

产出物 2 · 上下文映射图

明确标注:
- 上下文名称 + 主要聚合
- 上下文间的关系 (用 9 模式之一标注)
- 关键事件流方向

存放: 项目仓库 architecture/context-map.md
更新: 每季度 review 一次
1
2
3
4
5
6
7

产出物 3 · 通用语言术语表 v0.1

每个上下文一份
包含: 概念名 + 定义 + 同义词 + 反义词 + 代码命名
存放: 项目仓库 docs/glossary/{context}.md
更新: 持续维护 (第 3.4 节纪律)
1
2
3
4

产出物 4 · 待解决问题清单

墙上所有红色便利贴汇总
每条指派负责人 + Deadline
分类: 业务待定 / 技术待研究 / 跨团队沟通

跟进: 周会复盘进度
1
2
3
4
5

产出物 5 · 下一步行动计划

- 立项: 哪些上下文需要新建/重构
- 团队调整: 是否需要拆分/合并团队
- 优先级: 先做哪个上下文
- 度量: 用什么指标判断成功 (如开会沟通成本下降 50%)
1
2
3
4

红线:风暴开完不跟进 = 白开。3 个月内必须看到代码层面的变化(新仓库、新模型、新接口),否则就是新一份"贫血战略文档"。

# 10. 综合案例串讲

# 10.1 案例真相揭晓

回到第 1 章的 60 人团队"客户"五种含义事故,七个疑问现在能逐条作答:

疑问 答案
① 为什么"全公司一个统一模型"行不通? 第 8.1:87 字段大表导致字段膨胀、变更地狱、权限失控、语义混乱——业务概念本来就有边界
② 业务概念的边界怎么找? 第 4.2 / 4.3:同名异义识别法 + 四标尺打分(语言/规则/生命周期/团队)
③ 不同上下文里同名概念怎么共存又不打架? 第 6:9 种上下文映射模式,最常用的是防腐层(ACL)和领域事件
④ 哪些子域值得砸钱自研,哪些买就行? 第 5:核心子域重金自研(差异化竞争力),支撑适度,通用必买
⑤ 业务方和开发为什么经常"说同一个词不是一回事"? 第 3.2:翻译损耗——六层翻译信噪比剩 35%;统一语言可拉回到 90%+
⑥ 战略画完了,到代码层怎么落? 第 7:每个上下文内部独立做战术建模 + 通过事件/ACL 协作
⑦ 怎么把全公司业务模型一次理清? 第 9:事件风暴 3 天工作坊,效果 >> 6 个月架构会议

修复方案(按代价从小到大):

方案 A · 拆"客户"为多模型(推荐起步)

按上下文重建 5 个独立模型:
  - 认证上下文.Account     (5 字段: id, account, credential, status, createdAt)
  - 会员上下文.Member      (10 字段: memberId, level, points, joinDate, ...)
  - 营销上下文.Customer    (8 字段: customerId, tags, segments, rfm, ...)
  - 交易上下文.Buyer       (7 字段: buyerId, addresses, paymentMethods, ...)
  - 客服上下文.Complainant (6 字段: complainantId, contacts, tickets, ...)

跨模型协作通过:
  - 注册时 Account 发布 AccountRegisteredEvent → 触发 Member 创建
  - 下单时 Buyer 通过 BuyerId 引用,需要等级信息时调用会员上下文 API
  - 营销时 Customer 通过 ACL 同步会员数据 + 交易数据

代价: 2 个月重构,需要数据迁移
收益: 87 字段 → 5 个上下文各自 5~10 字段;变更地狱消失;权限可控
1
2
3
4
5
6
7
8
9
10
11
12
13
14

方案 B · 引入统一语言守护机制

立刻动作:
  - 5 个上下文各自建立术语表 (v0.1)
  - Code Review 加入"命名符合术语表"检查项
  - 新需求评审增加"概念明确"环节 (业务方必须给定义)
  - 每季度术语表 review

代价: 文化建设需 3~6 个月生效
收益: 跨团队歧义大幅减少,需求评审效率提升 50%+
1
2
3
4
5
6
7
8

方案 C · 调整组织结构(最激进)

原后端组 20 人拆分为:
  - 交易团队 5 人 (负责交易上下文)
  - 营销团队 5 人 (负责营销上下文)
  - 会员团队 4 人 (负责会员上下文)
  - 平台团队 6 人 (负责认证/通知/客服等支撑+通用)

每个团队完全负责自己的上下文:
  - 独立代码仓库
  - 独立数据库
  - 独立 CI/CD
  - 对外通过明确契约 (OHS + PL)

代价: 组织调整需 VP 级支持,3~6 个月磨合期
收益: 彻底符合康威定律,跨团队冲突归零
1
2
3
4
5
6
7
8
9
10
11
12
13
14

生产建议:方案 B 立刻做(成本低收益快),方案 A 排到下半年(系统性重构),方案 C 视组织意愿(最根本但阻力大)。三方案叠加 = 真正解决问题。

# 10.2 一次战略落地全过程

把"从战略到代码"的全过程串成一棵知识树:

决策"重新设计领域模型"
        │
        ├─ 准备阶段
        │   ├─ 业务复杂度评估 — 是否值得做战略设计
        │   ├─ 高层支持获取 — VP 级 sponsorship
        │   ├─ 关键人物到位 — 业务/产品/技术核心 lead
        │   └─ 物料准备 — 会议室、便利贴、记号笔
        │
        ├─ 发现阶段 (事件风暴大图,第 9.2 节)
        │   ├─ Day 1: 发散写事件 (200~500 张)
        │   ├─ Day 2: 收敛识别上下文
        │   └─ Day 3: 验证 + 上下文映射
        │
        ├─ 分类阶段 (第 5 章)
        │   ├─ 标注核心 / 支撑 / 通用子域
        │   ├─ 决定每个子域的投资策略
        │   ├─ 决定哪些自研、哪些买
        │   └─ 制定团队-上下文映射 (第 4.4 节)
        │
        ├─ 语言阶段 (第 3 章)
        │   ├─ 每个上下文起草术语表 v0.1
        │   ├─ 业务方 + 开发共同评审
        │   ├─ 进入代码评审检查清单
        │   └─ 建立日常维护机制
        │
        ├─ 集成阶段 (第 6 章上下文映射)
        │   ├─ 标注每对上下文之间的 9 模式
        │   ├─ 核心:防腐层 (ACL) 隔离外部
        │   ├─ 内部:领域事件解耦
        │   └─ 制定 SLA、版本化策略
        │
        ├─ 战术阶段 (第 7 章 + 设计级风暴)
        │   ├─ 每个上下文单独开 1~2 天设计级风暴
        │   ├─ 识别聚合根 + 命令 + 事件
        │   ├─ 设计资源库 + 领域服务
        │   └─ 决定与六边形/CQRS/事件驱动的搭配
        │
        ├─ 落地阶段 (与微服务拆分协同)
        │   ├─ 决定物理形态:模块化单体 / 微服务
        │   ├─ 数据库按上下文拆分 (一库一服务)
        │   ├─ 旧系统:绞杀者模式渐进迁移
        │   └─ 灰度切流 + 监控验证
        │
        └─ 反馈阶段
            ├─ 3 个月后复盘:边界画对了吗?
            ├─ 业务沟通效率是否提升?
            ├─ 跨上下文变更频率是否下降?
            ├─ 必要时调整 (上下文合并/拆分)
            └─ 下一次战略 review (回到准备阶段)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

理解一次战略落地的完整路径,就是理解为什么 DDD 是一种长期实践,不是一次性架构决策。每次战略 review 都应该让模型更贴近业务现实。

# 10.3 设计哲学回扣

整理本篇的四条跨架构适用的设计哲学:

哲学 1:边界即语言——同一个词在不同地方是不同的东西

最深刻的认知:没有"全公司统一的客户"——"客户"在登录、会员、营销、交易、财务、客服里本来就是六种不同的东西。强行统一就是把六个清晰的概念糅成一团泥。承认边界的存在,比假装边界不存在更接近真理。这条哲学是 DDD 战略的灵魂——也是为什么"限界上下文"要叫"限界"(Bounded)而不是"上下文"。

哲学 2:核心稀缺——资源永远要砸在差异化上

任何公司的核心子域只占 20~30%,但应得 50%+ 的资源。把核心子域当通用子域 = 自废武功;把通用子域当核心子域 = 资源浪费。清晰区分哪里是护城河、哪里是基建,是 CTO 级别的核心判断力。这条哲学不止用于 DDD——延伸到任何资源分配场景:技术选型、人力配置、预算分配,都遵循同样的二八法则。

哲学 3:语言即模型——业务和开发说同一种话

代码里的类名、字段名、方法名,必须与业务方嘴里的词一致。每多一层翻译就丢一层语义;六层翻译下来,业务原意只剩 1/5。统一语言不是"开发去背业务词"或"业务去学技术词"——是双方一起重新定义一套共用的词。这套词写进术语表、写进代码、写进文档,任何不符合的命名都视为债务。语言纪律是 DDD 落地与否的最终标志。

哲学 4:康威双向——组织决定系统,系统也反作用组织

正向:你团队怎么分,你的系统就长成什么样——三个团队画不出五上下文方案,方案再美也要碎裂。反向:想要的系统结构倒逼组织调整——想拆出独立上下文,必须先有独立团队负责。架构师的最高境界不是画好图,是推动组织调整以匹配图。这往往不是技术问题,是政治问题——能否成事,看你能不能让 VP 级支持。

# 10.4 战略设计速查

一张图保存以备查:

要素 用途 关键决策 输出物
领域 公司业务整体 一句话使命 使命陈述
子域 业务能力切分 核心/支撑/通用三级 子域地图
限界上下文 模型+语言+团队边界 同名异义识别+四标尺 上下文列表
通用语言 业务-开发共识词 术语表持续维护 术语表 v.x
上下文映射 上下文协作关系 9 模式选其一 映射图

九种上下文映射模式速查:

模式 适用 关键词
Partnership 深度协作的核心上下文 共担成败
Shared Kernel 极少数稳定公共模型 共享代码(慎用)
Customer/Supplier 内部上下游 有发言权
Conformist 强势外部系统 不抗争
ACL(防腐层) 外部/老旧系统对接 ★ 翻译适配
Open Host Service 核心上游多下游 标准化接口
Published Language 跨组织协议 共同协议
Separate Ways 业务无关 主动不集成
Big Ball of Mud 反模式 必须重构

战略落地决策树:

                  开始 DDD 战略
                       │
                       ▼
                业务复杂度足够大?
                 (10+ 概念交织)
                /            \
              是              否
              ↓               ↓
        开事件风暴大图     不需要 DDD
              ↓           直接分层架构
        识别上下文 (3~10个)
              ↓
        子域分类:
        核心/支撑/通用
              ↓
        团队与上下文对齐?
        /              \
       是              否
       ↓               ↓
    起草术语表      要么调团队
       ↓           要么调上下文 (合并)
    标注上下文映射
       ↓
    设计级风暴每个上下文
       ↓
    选物理形态:
    模块化单体 / 微服务
       ↓
    与六边形/CQRS/事件驱动联动
       ↓
    持续演进 + 定期 review
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

60 秒诊断命令清单(用于判断现状):

# 看是否有"统一大模型"症状
grep -r "class User\b\|class Customer\b" src/ | wc -l   # 用户/客户类被引用次数
mysql> DESC customer;                                   # 看主表字段数

# 看是否有"翻译损耗"症状
grep -E "// 业务说.*实际是" src/                          # 注释里出现"业务说"
git log --grep="字段含义" --oneline | wc -l               # 因字段含义产生的提交

# 看是否有"贫血战略文档"症状
ls docs/architecture/                                   # 架构文档最后更新时间
git log --follow docs/glossary.md --since="6 months"   # 术语表 6 个月内是否更新

# 看是否有"组织失配"症状
cat CODEOWNERS | sort | uniq -c                         # 同一模块多 owner = 失配
git log --pretty='%ae' --since='3 months' src/order/ | sort -u | wc -l
                                                        # 同一目录贡献者数量

# 看上下文物理边界
find . -name "package.json" -o -name "pom.xml" | head   # 仓库数量
docker ps | grep production | awk '{print $NF}' | sort -u | wc -l
                                                        # 服务数量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

战略设计黄金法则:

业务理解:     业务方和开发说同一种话 (统一语言)
边界识别:     同名异义 + 四标尺 + 团队归属
子域投资:     核心重金自研、支撑适度、通用必买
上下文映射:   默认 ACL,跨域用事件,绝不共享模型
组织对齐:     模型与团队 1:1,失配必须调整
战术衔接:     上下文内独立战术建模,聚合内 ID 引用
持续演化:     每季度 review,术语表常更新,文档进代码
反模式警惕:   统一大模型/机械微服务/贫血文档/组织失配
落地节奏:     先模块化单体,再选择性微服务,绝不大爆炸
红线纪律:     代码命名 ≠ 术语表 → reject;新词无定义 → 不评审通过
1
2
3
4
5
6
7
8
9
10

第 1 章案例:60 人 SaaS 公司"客户"五种含义 → 拆为 5 个上下文独立模型 + 统一语言守护 + 组织调整 → 跨团队沟通效率提升 60%,需求误传问题归零,新人入职上手周期从 2 个月缩到 2 周。这就是"边界 + 语言 + 组织"三位一体给团队的核心红利。


下一篇:我们已经知道了"如何识别和组织业务边界",下一步进入 07.架构评审方法论——把"架构设计"从直觉判断升级到 ATAM/质量属性场景/风险风暴等可重复的方法论框架。

上次更新: 2026/06/17, 11:43:57
微服务拆分策略
架构评审方法论

← 微服务拆分策略 架构评审方法论→

最近更新
01
信号崩溃快速排查
06-15
02
CoreDump破案
06-15
03
perf火焰图实战
06-15
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式