架构文档最大的敌人是"过时"。而真正有价值的信息不是"系统长什么样",而是**“当初为什么这么决定”**——这正是 ADR(Architecture Decision Record)存在的原因。本文讲透 ADR 的结构、写法、生命周期与团队落地,让决策"有据可依、可追溯、可反转"。
1. 什么是 ADR,为什么需要它
1.1 传统架构文档的痛点
- 架构图/设计文档很快过时,没人维护;
- 决策散落在聊天记录、会议纪要里,后来者无从查证;
- “为什么用 A 不用 B”只存在于当事人脑中,人走了知识就没了。
1.2 ADR 是什么
ADR = 一条记录:在某时某地,针对某个问题,权衡了哪些选项,为什么选了当前方案,有哪些后果。
它像"git commit 消息"一样增量、原子、可追溯地记录决策史,而不是一份整体大文档。
1.3 带来的价值
| 价值 | 说明 |
|---|---|
| 决策可追溯 | 谁、何时、为何选了这条路 |
| 新人速通 | 看 ADR 就能懂系统设计的历史脉络 |
| 争议终结 | “为什么不用 X” → 翻 ADR,避免重复争论 |
| 反转可记录 | 环境变了,新 ADR 记录推翻旧 ADR |
一句话:ADR 是**“架构决策的提交记录”**——把"为什么"固化下来,让团队告别"看代码猜意图"。
2. ADR 的标准结构
业界通行的是 Michael Nygard 模板,虽短但五脏俱全:
# ADR-001:订单服务采用事件驱动而非同步 RPC
## 状态
已接受(Accepted)
## 背景(Context)
订单创建后需要通知库存、积分、通知三个模块;
原实现为同步远程调用,三个下游任一慢都会拖垮下单链路。
## 决策(Decision)
订单模块发布"订单已创建"领域事件,
库存/积分/通知异步订阅处理。
## 后果(Consequences)
- 正面:下单响应更快、下游故障隔离;
- 反面:引入最终一致性,需幂等与补偿;
- 额外:需要事件总线基础设施。
## 备选方案(Alternatives / Rejected)
- 同步 RPC:链路耦合,下游慢拖垮主流程(否决);
- 定时对账:时效差,账务不实时(否决)。
| 段落 | 作用 |
|---|---|
| 状态 | 提案/已接受/已弃用 |
| 背景 | 为什么需要决策(问题+约束) |
| 决策 | 最终选什么(一句话说清) |
| 后果 | 正反后果、成本 |
| 备选 | 考虑过哪些,为何否决 |
一句话:ADR 模板的核心是**“背景 → 决策 → 后果 → 备选”**四件套;写清了它,别人就能"看到你的思考过程",而不只是结果。
3. 记什么、不记什么
3.1 该记的决策
- 有多个可选方案的:选型(DB/框架/消息队列/部署方式);
- 影响大、难回头的:数据库分库分表、微服务拆分;
- 反复被问"为什么"的:某种设计模式、某条技术路线;
- 成本高的:引入新基础设施、新团队协作方式。
3.2 不该记的
- 日常实现细节(方法名、变量命名);
- 无选择的既定事实(“服务用 HTTP”——除非有过抉择);
- 可立刻撤销的临时决定。
3.3 判断口诀
“这个决定如果三个月后被问起,我能说清为什么吗?说不清 → 记一条 ADR。”
一句话:ADR 记**“有抉择、难回头、常被问”**的决策;平凡细节别进库,保持 ADR 库"短小精悍"。
4. ADR 的生命周期:提案、接受、弃用
4.1 状态机
提案 Proposed → 已接受 Accepted(经评审/试用)
→ 已弃用 Deprecated(被新 ADR 取代)
→ 已作废 Superseded
4.2 决策反转怎么写
技术环境变了,原决策被推翻——不要改旧 ADR,而是新增一条 ADR 并引用旧的:
# ADR-012:改用 xxx,取代 ADR-003
## 状态
已接受
## 背景
ADR-003 选择方案 A;如今 xxx 生态成熟/团队规模变化……
## 决策
改用 xxx。
## 后果
- 需迁移期、兼容策略……
4.3 反转的触发信号
- 新技术成熟、原方案的痛点变得不可忍受;
- 团队规模/业务阶段变化;
- 原方案的隐性成本暴露。
一句话:ADR 的"历史"不能改,只能"续写"——决策反转不是删记录,而是新 ADR 覆盖旧 ADR,完整决策史因此保留。
5. 轻量落地:文件即 ADR
5.1 存储方式
最轻量、最普适的落地是把 ADR 放代码仓库(跟代码走,天然版本化、评审即 PR):
docs/adr/
0001-order-event-driven.md
0002-use-postgres-for-orders.md
README.md # 索引表
- 序号递增,永不重排;
- 随代码提交,合入 PR,决策与实现同步被评审;
- 不需要额外文档系统。
5.2 模板与工具
# 模板文件 docs/adr/_template.md
cp docs/adr/_template.md docs/adr/0015-use-kafka-for-events.md
# 或用工具自动编号:adr-tools / adr-gen(生成模板、更新索引)
一句话:ADR 放代码库是性价比最高的落地方式——版本管理、评审、搜索、权限全都有了,还不用养一套文档系统。
6. ADR 文化:让团队"先记再写代码"
6.1 推行四步
- 从高频痛点开始:先给最近吵过/被反复问的选择补 ADR,立竿见影;
- 短小模板:一页纸能写完,别写长文;
- 评审绑定:涉及选型的 PR 必须附 ADR;
- 新人必读:入职文档把 ADR 库作为第一站。
6.2 反模式
| 反模式 | 表现 | 对策 |
|---|---|---|
| 长篇大论 | ADR 写成设计书 | 一页纸原则,写不下就是没想清 |
| 只写结论 | 无背景/备选 | 模板强制四段 |
| 决策后补 | 走个过场 | 重大决策先 ADR 再实现 |
| 一人垄断 | 决策闭环 | 评审 + 轮流执笔 |
一句话:ADR 文化 = “先记录、再评审、后实现” + 一页纸短模板;真正让它活起来的是"争议出现时大家习惯去翻 ADR 库"。
7. ADR 与架构评审、技术债的配合
- 架构评审(ATAM)输出决策建议 → 沉淀为 ADR;
- 技术债清单里"当年为赶进度绕过的方案" → 记 ADR 注明技术债成因与偿还方案;
- 季度复盘 → 按 ADR 状态机看有多少"已弃用",评估架构演进健康度。
一句话:ADR 是评审与技术债治理的"证据层"——评审结论落成 ADR,技术债成因写进 ADR,演进才可复盘。
8. 踩坑清单
| 坑 | 现象 | 对策 |
|---|---|---|
| ADR 写成设计书 | 没人读 | 一页纸 + 四段模板 |
| 决策后补流程化 | 流于形式 | 选型 PR 强制附 ADR |
| 改旧 ADR 而不是新增 | 历史失真 | 反转必须新增覆盖 |
| 记了太多琐碎决策 | 库膨胀没人看 | 过滤"无抉择"的决策 |
| ADR 与代码脱节 | 仓库不更新 | ADR 放代码库,随 PR 评审 |
| 只有结论没备选 | 无法复盘 | 模板强制背景+备选 |
9. 总结
| 环节 | 要点 |
|---|---|
| 是什么 | 一条"决策 commit",记录为什么 |
| 结构 | 背景→决策→后果→备选 |
| 记什么 | 有抉择、难回头、常被问 |
| 反转 | 新增覆盖旧,不改历史 |
| 落地 | 放代码库 docs/adr,随 PR 评审 |
| 文化 | 先记录再实现,一页纸原则 |
一句话记住:ADR 是对"架构决策"的版本管理——把每次"为什么这么选"固化下来,团队就有了可以追溯、可以反转、可以复盘的系统级记忆。写 ADR 不花时间,不写才花时间(反复争论、新人猜谜)。
延伸阅读
- 架构评审与技术债管理 — 决策评审与债务治理
- 架构设计基础原则 — 决策背后的原则依据
- 技术选型与决策框架 — 演进中的决策如何保持开放
- 架构模式与设计模式 — 决策落地到模式选择
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。