ADR 架构决策记录
- S:在学习和实践“架构决策记录(ADR)”时,需要建立统一的概念和问题边界。
- C:模板、生命周期和组织流程各有各的说法,概念和工程取舍容易混在一起,导致只记住结论而无法判断适用条件。
- Q:ADR 到底解决什么问题?字段怎么挑、生命周期怎么走、与架构文档有什么关系?
- A:本文围绕 ADR 整理其目的、可实操字段、生命周期、组织流程与反模式,并给出与 ADL/架构文档/wiki 的定位差异。
ADR 是什么、解决什么问题
ADR(Architecture Decision Record)是一份短文档,记录团队就某个架构重要决策(architecturally significant decision)所做的选择:决策本身、上下文(Context)与后果(Consequences)。
- 解决“why 丢失”:代码和文档都在,但“当初为什么这么选”最容易丢。ADR 聚焦理由(why)而非实现(how),让未参与决策的人能接受它,也防止未来不知情的架构师凭直觉推翻它。这与 软件架构基础 把“为什么比怎么做重要”列为架构第二定律的立场一致。
- newcomer onboarding:新成员面对旧决策常“困惑、恼火”,没有 rationale 时只能盲目照做或凭猜测返工。ADR 集合提供交接体验(hand-over)与项目上下文总览:先扫标题、再深读单条。
- 写即思考:写作本身会暴露分歧、逼出讨论并达成一致——记录不是为了存档,是为了把决策想清楚。
- 记什么:影响结构(如微服务模式)、非功能特性(安全、高可用)、依赖耦合、接口与公开契约、构建技术与流程,以及难以逆转或影响关键质量属性的选项。
模板字段清单
- Nygard 经典模板(2011):五个字段
Title / Status / Context / Decision / Consequences,文件置于doc/arch/adr-NNN.md。Context 用价值中立语言描述 forces(技术/政治/社会/项目局部);Decision 用主动语态完整句 “We will…”;Consequences 正、负、中性后果都要列出。 - MADR(Markdown Any Decision Records):YAML 元数据
status / date / decision-makers / consulted / informed,章节含 Context and Problem Statement、Decision Drivers、Considered Options、Decision Outcome、Consequences(Good/Bad)、可选 Confirmation 与 Pros and Cons of the Options。
落地时按必选/建议/可选分层,避免一上来就被完整模板吓退:
- 必备:编号(唯一标识)、Title(现在时祈使句)、Status、Date、Context、Decision(“We will…”祈使语气,避免 should)、Consequences(正/负/中性权衡)。
- 建议:Decision Drivers、Considered Options(含被拒方案及理由)、Author/Owner、Deciders、Confidence(置信度)、Changelog、指向被取代 ADR 的链接。
- 可选:Consulted/Informed、相关架构原则、Confirmation(落地验证方式,如设计评审或架构测试)、More Information 外链。
生命周期
- 状态机一句话:
Proposed → Accepted / Rejected;Accepted → Deprecated / Superseded。 - 起草即置
Proposed进入评审;通过 →Accepted(补时间戳、版本、干系人);否决 →Rejected并记录原因,防止日后重复争论同一话题。 - append-only 不可变:接受或否决后不回头编辑旧记录——可追溯性靠的是“不改变历史”。
- 更新走“新 ADR + 旧状态标注”:决策变了就新建 ADR 走完整评审,批准后旧 ADR 标
Superseded并链到新 ADR。实践上最好在同一个 PR 里同步旧状态,否则新成员会照过时决策实现。 Deprecated与Superseded并列使用(Nygard 原文):被取代的旧 ADR 保留原文,只标记状态并附替代者引用——知道它曾是决策仍然重要。
组织流程
- 决策发生时写,而非事后补(见反模式);项目开端即建 ADR 并贯穿生命周期,brownfield 项目可按已知历史决策追溯补录(AWS、Microsoft 均认可)。
- 任何人可写,设 Owner:Owner 负责维护与沟通,改动需 Owner 批准;作者通常来自含 tech lead 的小组。
- PR 评审:接受前至少评审一次;评审会可先留 10–15 分钟静默阅读、再逐条讨论批注;以 PR 形式提交,评审常能暴露未考虑的约束。
- 放代码仓库与代码同步:
doc/adr/doc/arch/adr-NNN.md,与代码同版本控制、可 diff、随代码演进保持同步;轻量 markdown 文本即可。 - review 钩子与过时重审:在新模式/依赖/接口的 PR 与设计评审中关联相关 ADR;架构评审周期性重审过时决策并及时
Superseded;Confirmation 节可用代码评审或架构测试(如 ArchUnit)验证落地。
最佳实践
- 小而聚焦:通常一页、最多几页;倒金字塔写作(结论先行),长篇材料外链。
- 一 ADR 一决策:每个决策有独立生命周期;一个决策若分短/中/长期多阶段,拆成多条记录。
- 记录替代方案及拒绝理由:列出所有认真考虑过的备选及其 pros/cons——这是防止未来“重开讨论”的防火墙。
- 决策与讨论分离:ADR 记结论与理由;建议与讨论细节另存,正文只摘要(Advice Process)。
- 写后果预判而非事实:Consequences 写成“接受该决策后的预判(forecast)”而非事后结果;记录置信度与“何种情况变化应触发重评”。
反模式清单
- 事后补写:几个月后补,上下文已丢、备选被忘、后果变成结果描述。“ADR 是决策的一部分,不是决策的产物。”
- 记录所有琐碎决策:ADR 沦为 “Any Decision Record”,架构决策被淹没——如果每个决策都是架构决策,就没有架构决策。
- Mega-ADR 当文档仓库:塞入组件职责、架构图、代码片段、运行步骤;它不替代 README/设计文档/runbook。
- 过时无人维护:标着 Accepted 的系统早已更换,新成员照着做白费数天;取代旧决策时同步更新其状态。
- 改写历史:编辑已接受记录破坏可追溯性;应新建 ADR 并标
Superseded。 - 只写正面后果:隐藏权衡的 “Free Lunch Coupon” —— ADR 不是新闻稿。
- 一人写一人批,无讨论;虚假备选(Dummy Alternative)、只看短期(Sprint 视角)、局部视角(Tunnel Vision)。
- CYA 甩责:把决策记录当免责声明,是毒性管理文化的信号;应鼓励小步试验而非自我辩护。
与 ADL、架构文档、wiki 的定位差异
- ADL(Architecture Decision Log)= ADRs 的集合:一条 ADR 一个决策,集合即决策日志,提供项目上下文总览。
- why vs how:architecture design specification 描述“how”(结构、图、契约、实现计划),随系统演进持续更新;ADR 记录“why”,接受后不可变。职责三分:RFC 提议(可变)→ ADR 记录决策(不可变)→ design doc 描述建成之系统(持续更新)。
- 与 wiki:ThoughtWorks 明确偏好存源码仓库而非 wiki——与代码同步、可审查可 diff;Google 承认 wiki 更便于跨团队/业务干系人访问,可选“源码为主 + 镜像关键决策到 wiki”。
- 一句话定位:runbook = 怎么运维,README = 怎么用,架构文档 = 系统长什么样,ADR/ADL = 为什么长成这样、决策如何随时间演化。上述生命周期与文档职责划分,都是 架构 这个主题在工程实践上的具体化。
links
- https://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/architectural-decision-records/adr-process.html
- https://docs.cloud.google.com/architecture/architecture-decision-records?hl=zh-cn
- https://learn.microsoft.com/zh-cn/azure/well-architected/architect-role/architecture-decision-record
- Michael Nygard: https://www.cognitect.com/blog/2011/11/15/documenting-architecture-decisions
- martinfowler.com: https://martinfowler.com/bliki/ArchitectureDecisionRecord.html
- MADR: https://adr.github.io/madr/
- joelparkerhenderson 模板集: https://github.com/joelparkerhenderson/architecture-decision-record
- ThoughtWorks Technology Radar: https://www.thoughtworks.com/radar/techniques/lightweight-architecture-decision-records
评论