3651 字
约 12 分钟
10
S18-X03 · DDD 术语与建模模板速查

适用读者:要把 DDD 推给团队、需要一份"大家说同一个词"的对照表的人;写建模文档时不想每次重造模板的人。
前置:S18-J06、S18-A01、S18-A02(机制与结构)。
覆盖旧文:A-1527(小册介绍 107 点)、A-1528(交互式学习 42 点)、A-1537(题名"DDD建模案例",实为 NAS 随笔 71 点)——合计 220 点,全部 non_knowledge(推广/目录/与主题无关),本文只登记不搬运。
扩展点:本篇不新增 E 点,交叉引用 E-S18-014/015/016/018/023。
上一篇:S18-X01 · 23 种设计模式速查表
下一篇:无(系列终篇);返回 S18 主页。


1. 怎么用这篇

三部分:

  1. §2 术语表:40 条,每条一句定义 + 出处小节(指回本系列哪一篇讲透的);
  2. §3 建模模板:四张可复制的表(事件风暴、聚合清单、上下文映射、分层检查);
  3. §4 素材异常与跨系列边界:说明哪些旧卡不能用、为什么,以及本系列与其它系列的接管关系。

术语表的用法:评审时如果两边对同一个词的理解不一致,先查这张表,再查表里给出的出处小节。不要靠记忆争论定义——这正是"统一语言"的字面意思。


2. 术语表(40 条)

2.1 战略设计(10 条)

术语 一句话定义 出处
领域 Domain 业务问题空间的一个范围(如"账户""交易") A01 §1
子域 Subdomain 领域内部的进一步划分,分核心/支撑/通用 A01 §1
核心域 Core Domain 决定竞争力的那部分,投最强的人 A01 §1
支撑域 Supporting 必须做但不构成竞争力(如内部审批) A01 §1
通用域 Generic 可买可开源(如认证、邮件) A01 §1
限界上下文 Bounded Context 一个模型适用的边界;边界内词义唯一 A01 §1、§3
统一语言 Ubiquitous Language 团队与代码共用的一套词,冲突处即边界 A01 §1
上下文映射 Context Map 描述上下文之间"谁迁就谁的模型"的图 A01 §3
事件风暴 Event Storming 用便签穷举事件/命令/对象并圈边界的建模活动 A01 §2
四色建模 事件风暴的便签配色法(命令/事件/对象/外部/只读/流程) A01 §2

2.2 战术设计(14 条)

术语 一句话定义 出处
实体 Entity 有唯一标识、标识在生命周期内不变的对象 J06 §3
值对象 Value Object 无标识、不可变、按值相等的对象 J06 §3
聚合 Aggregate 一组必须一起改的对象的集合,是一致性与事务边界 J06 §3
聚合根 Aggregate Root 聚合的唯一入口,外部只能通过它访问内部 J06 §3
不变式 Invariant 任何时候都必须成立的业务规则(如余额 ≥ 0) J06 §3、§2
领域服务 Domain Service 无法自然归属到某个聚合的业务规则 J06 §5
应用服务 Application Service 编排用例、管事务,不含业务规则 J06 §5、A02 §3
领域事件 Domain Event 领域内已发生事实(过去时命名) J06 §5
仓储 Repository 以聚合为粒度的持久化抽象,接口由领域定义 J06 §4
工厂 Factory(领域内) 封装聚合的复杂创建过程 J02 §3、J06 §3
端口 Port 领域定义的外部能力接口(仓储/适配器) J06 §4
适配器 Adapter(端口实现) 基础设施层对端口的实现 J06 §4、J03 §4
防腐层 ACL 下游为隔离上游模型而加的翻译层 A01 §3
发件箱 Outbox 事件与业务数据同事务落库,再由投递器发出 J06 §5

2.3 工程与架构(10 条)

术语 一句话定义 出处
分层架构 Layered 按职责分层,依赖单向 A02 §3
六边形架构 Hexagonal 入口与出口对称(端口-适配器) A02 §2
洋葱架构 Onion 依赖只能向内,核心是领域 A02 §2
整洁架构 Clean 显式 Use Case 层 + 适配器层 A02 §2
触发器 Trigger HTTP/RPC/MQ/JOB 的统一入口层 A02 §3
编排层 Case/Application 串联多个领域服务的可选层 A02 §3
贫血模型 Anemic Model 只有数据没有行为的对象 + 逻辑全在 Service J06 §1
充血模型 Rich Model 属性 + 行为 + 校验聚合在对象内 J06 §1
依赖倒置 DIP 高层与低层都依赖抽象,接口归高层定义 J05 §1、A02 §3
类型分包 / 领域分包 按技术角色分 vs 按业务领域分 A02 §3(E-S18-018)

2.4 演进与分布式(6 条)

术语 一句话定义 出处
绞杀者 Strangler Fig 在外面长新实现,逐步替换旧实现 A03 §4(E-S18-020)
CQRS 读写模型分离,可选,非 DDD 组成部分 J06 §6
事件溯源 Event Sourcing 以事件序列作为唯一真相,可选 J06 §6
Saga 跨聚合/跨服务的长事务补偿编排 A04 §5(E-S18-026)
幂等 Idempotency 同一操作重复执行结果一致 A04 §4(E-S18-025)
爆炸半径 Blast Radius 单点故障影响的请求占比 × 时长 A04 §3(E-S18-022)

2.5 五组最容易混的术语

容易混 一句话区分 判断问法
聚合 vs 实体 聚合是边界,实体是身份 "这些对象要不要在一个事务里改?"
领域服务 vs 应用服务 前者含业务规则,后者只编排 "这里面有没有业务判断?"
仓储 vs DAO 前者以聚合为粒度,后者以表为粒度 "这个方法操作的是聚合还是表?"
端口 vs 适配器 前者是领域定义的接口,后者是基础设施的实现 "这个接口写在哪个模块?"
限界上下文 vs 微服务 前者是模型边界,后者是部署单元 "拆开部署是必须的吗?"

记忆锚点:凡是"边界/身份/规则/粒度/归属"这类问题,答案都在领域层;凡是"部署/协议/框架/驱动"这类问题,答案都在基础设施层。分不清一个概念属于哪边时,问"如果换掉数据库/换掉框架,它要不要改"——要改的就在基础设施侧。


2.6 DDD 与 ADR 的关系

DDD 的建模产出(上下文映射、聚合清单)是设计事实,ADR 是决策记录,两者不能互相替代:

产出 回答什么 更新频率
上下文映射表 现在系统长什么样 每季度
聚合清单 现在模型长什么样 每次模型变更
ADR 为什么当时这么选、备选是什么、代价是什么 只增不改(新 ADR 取代旧 ADR)

判据:"是什么"进建模文档,"为什么"进 ADR。把所有内容塞进 ADR,会让 ADR 变成没人看的流水账;只写建模文档,则三个月后没人记得为什么这样划边界(ADR 模板见 A04 §6,E-S18-023)。


3. 建模模板(四张表,可直接复制)

3.1 事件风暴便签模板(E-S18-014)

颜色 要素 写法 例子
黄 领域事件 过去时 + 业务名词 抽奖完成、奖品发放完成
蓝 决策命令 动词短语(用户动作) 开始抽奖、查看额度
棕 领域对象 名词(承载命令状态) 抽奖单、活动账户
粉 外部系统 系统名 + 调用目的 积分系统(扣积分)
绿 只读模型 查询名 额度查询视图
红 业务流程 箭头串起命令→事件 签到→发券→入账

验收:一场风暴必须产出 5 样东西——事件清单、命令-事件映射、对象清单、外部系统清单、边界草图(A01 §2)。

3.2 聚合清单模板(E-S18-011)

字段 填写要求 反例
聚合根 一个名词 + 唯一标识来源 OrderManager(动词化)
不变式 用"必须/不得"写,可测试 "尽量保证一致性"(不可测)
内部对象 只有"必须同时改"的才列进来 把 Customer 整个对象塞进来
跨界引用 只存 ID 存对象引用
领域事件 过去时 + 触发时机(事务内/提交后) "支付相关事件"
仓储方法 以聚合为粒度(save/find) updateStatusById(表粒度)
事务边界 明确"一个事务里改哪些" 不写(默认全在一个事务)

3.3 上下文映射表模板(E-S18-016)

上游 下游 关系类型(九选一) 契约/接口 谁承担翻译成本 负责人 变更通知机制
账户域 交易域 OHS + Published Language /api/limit/query(JSON Schema v2) 下游(ACL) 张三/李四 契约变更需 2 周预告

填不出来的格子就是风险点:关系类型空着 = 没人想过耦合方式;"谁承担成本"空着 = 出事时互相推。

3.4 分层检查清单(E-S18-018 / E-S18-017)

  • domain 包的 import 里没有框架(Spring/MyBatis/Dubbo);
  • domain 不依赖 infra/trigger/app(ArchUnit 规则,见 A02 §4);
  • trigger 不直接依赖 infra;
  • PO 不出现在 domain 的方法签名里;
  • 仓储接口在 domain,实现在 infra;
  • @Transactional 只在 app 层;
  • 分层依赖无环。

4. 素材异常与跨系列边界

4.1 三张"不能直接用"的卡

卡 题名 实际情况 处理
A-1537 DDD 建模案例 源文是 NAS 硬件采购随笔(选购、Docker、SSH),与 DDD 无关 non_knowledge(71 点),本文 §3 的建模模板由 J06/A01 正文补足
A-1527 小册介绍 付费小册的推广页 + 目录(工程脚手架 1 + 系统架构 5 + 环境 6 + 技术 11……) appendix/non_knowledge;只保留目录结构作为"章节清单"参考
A-1528 菜鸟教程-交互式学习 学习站介绍(课程目录、SpringBoot/DevOps 示例) non_knowledge(42 点)

A-1527 的目录有一处可用信息:它的"系统架构(5)"列出了 MVC 架构 / DDD 架构 / MVC2DDD / DDD 架构-账户域 / DDD 架构-交易域——这正好解释了为什么素材里有 A-1539(账户域)、A-1540(交易域)两张未发布空卡:原书计划里有这两章,但导出时正文为空。A01 §4 因此给出了推断提纲。

4.2 与相邻系列的边界(避免二次真相)

主题 主讲系列 本系列的分工
Java 接口/泛型/反射/动态代理 S04 只讲"用它们实现哪个模式",不重讲语言机制
Maven 多模块、依赖管理、构建 S06 只讲"模块怎么对应分层",不讲 pom 细节
事务与隔离级别 S07、S11 只讲"聚合内事务/聚合外最终一致"的边界
分布式一致性、消息、事务、ID S17 只讲"架构取舍与参数",机制细节指回 S17
缓存一致性与失效 S11、S17 只讲 J05 §4 的"方案谱系 + 判据"
测试与代码质量 S16 只讲"架构规则怎么被测试守住"(ArchUnit)

判据:同一个知识点只在一处写全,其它处只写"判据 + 指路"。这是本系列 duplicate_ref 733 点的由来——设计模式八股的重复导出、A-2412 的三份导出、A-2609 的原则章节,全部按这条规则处理。


4.5 用术语表时的三个误区

误区 真相
把术语表当"标准答案"背 它只是团队约定的锚点;不同团队可以有不同的统一语言,只要内部一致
用术语数量衡量团队 DDD 水平 能说清"聚合边界与不变式"比能背 40 个词有用得多
术语表写完就归档 它必须和代码同步(类名、包名、事件名),否则会变成"文档里的另一个系统"

维护口径:术语表每次建模评审后更新一次;新增术语必须同时写"出处小节",没有出处说明它还没被真正使用。


5. 自测

  1. 你能用一句话说清"限界上下文"与"微服务"的区别吗?
  2. 值对象与实体的判断,只需要问哪一个问题?
  3. 聚合清单里"不变式"一栏,写"保证数据一致"为什么不算合格?
  4. 上下文映射表的哪一列空着最危险?
  5. 为什么本系列把 A-1537 判为 non_knowledge?
  6. 说出三个"本系列只给判据、细节在别处"的例子。

下一篇

无。本系列 12 篇到此结束。返回 S18 系列主页 可从阅读顺序与验收摘要继续。


本篇属于系列《S18 · 架构方法与领域建模》。素材:A-1527/A-1528/A-1537(全部 non_knowledge,仅登记);术语定义综合 A-1533/A-1534/A-1535/A-1536/A-1538 与 Evans《领域驱动设计》、Fowler bliki;模板为对 A-1534 四色建模与 A01/A02 清单的整理。

S18-X03 · DDD 术语与建模模板速查
https://www.clxhxhhr.top/posts/5450/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。