架构决策记录(ADR)实用指南


什么是架构决策记录(ADR)?为什么要用?怎么用?

1. 什么是架构决策记录(ADR)?
简单说,ADR 就是一份简短的文档,记录你在软件项目中做的一个重要决定,比如为什么选这个技术、为啥这样设计系统。它就像一个“决策日记”,记录了:

  • 做了啥决定(比如用 GraphQL 做 API)
  • 为啥要做这个决定(背景、原因)
  • 考虑了啥替代方案(最多3个)
  • 这个决定有啥影响(好处和坏处)
ADR 通常是个 Markdown 文件,存在代码库里,或者写在 Wiki、Notion 这种文档平台上。它不是随便记点啥,而是专门记录那些对系统结构、性能、依赖关系等有重大影响的决定。2011 年 Michael Nygard 提出了这个概念,目的是让团队的架构知识不随着人员流动而丢失。

一句话总结:ADR 是记录重要架构决定的“备忘录”,让团队明白为啥这样设计。

2. 为什么要用 ADR?
写 ADR 的核心目的是保留知识、减少误解、提高协作。具体好处有:

  • 知识留存:团队成员可能离职,但 ADR 能把决定背后的原因留下来。几个月或几年后,新人也能快速搞懂为啥这么干。
  • 团队协作:写 ADR 逼着大家讨论清楚,达成共识,防止拍脑袋决定。
  • 支持架构演变:需求变了,技术老了,ADR 能帮你看当初为啥选这条路,需不需要改。
  • 避免踩坑:没有 ADR,关键决定可能埋在邮件或聊天记录里,查起来费劲,容易导致误解和错误。比如,作者讲了个真实故事:因为没写 ADR,他花了一周时间查为啥选了 Cosmos DB,而不是 Azure SQL,差点让客户质疑能力。
大白话举例:你盖房子,决定用钢筋混凝土而不是木头,但没写下来为啥。两年后新来的建筑师问:“为啥不用木头?便宜多了!”你得翻旧邮件、找老同事问,才能解释清楚当初是为了抗震。如果有 ADR,一查就知道原因,省时省力。

3. 怎么开始用 ADR?
用 ADR 很简单,不需要复杂工具,Git 或者 Wiki 就能搞定。
方法一:用 Git

  • 在代码库里建个文件夹,比如 docs/adr/。
  • 每次有重要决定,写个 Markdown 文件(比如 001-use-graphql.md)。
  • 写好后提交,团队审核,合并到代码库,像代码审查一样。
  • 好处是跟代码放一起,版本控制清楚,谁改了啥一目了然。

方法二:用 Wiki 或文档平台

  • 在 Confluence、Notion 或 Google Docs 里建个“架构决策”页面。
  • 每个 ADR 写成一个条目,带版本历史,方便非开发人员(比如经理)看。
  • 缺点是跟代码关联没那么紧密,但更适合非技术团队。

方法三:专用工具

  • adr-tools:命令行工具,帮你快速生成 Markdown 格式的 ADR。
  • Log4brains:能把 ADR 发布成静态网站,方便浏览。
  • dotnet-adr:适合 .NET 开发者,支持多种模板。
  • Structurizr:可以把 ADR 和架构图结合,适合复杂项目。

建议:小团队直接用 Git + Markdown 就够了,简单高效。复杂项目可以试试专用工具。

4. 怎么写一份好 ADR?
写 ADR 得简洁、清晰、经得起时间考验。以下是关键原则:

  • 一个 ADR 只写一个决定:别把好几个决定塞一起,相关的决定可以写多个 ADR 互相引用。
  • 别太长:1-2 页,最多几分钟读完。删掉不必要的细节,问自己:“未来团队需要这信息吗?”
  • 讲清楚背景:为啥要做这个决定?有啥需求、限制、技术或业务驱动?
  • 明确决定内容:直接说“我们决定用 X”,别含糊。
  • 写出后果:好处(比如性能提升)、坏处(比如学习成本)、后续任务(比如要监控啥)。
  • 一经接受不改动:ADR 是历史记录,改决定就写新的 ADR,别改旧的。
简单模板(基于 Michael Nygard 的格式):
# 标题:[简短描述,比如“用 GraphQL 做搜索 API”]

<strong>状态</strong>
[提议中 | 已接受 | 已废弃 | 被 ADR-X 取代]

<strong>日期</strong>
YYYY-MM-DD

<strong>背景</strong>
[为啥要做这个决定?有啥问题或需求?]

<strong>决定</strong>
[明确说做了啥决定]

<strong>后果</strong>
<strong>好处</strong>
- [好处1]
- [好处2]

<strong>坏处</strong>
- [坏处1]
- [坏处2]

<strong>替代方案</strong>
[考虑了啥别的选项?为啥没选?]

<strong>参考资料</strong>
[可选:相关文档、链接]

真实例子

# ADR 7 - 用 GraphQL 做产品搜索 API

<strong>状态</strong>
已接受

<strong>日期</strong>
2025-03-15

<strong>背景</strong>
我们电商平台要加个产品搜索服务,供网页、手机、第三方用。需要灵活的 API,响应时间低于 2 秒。之前用 REST 要建很多端点,数据经常多抓或少抓,维护多个版本也麻烦。团队对 GraphQL 不熟,但想试试更灵活的查询方式。

<strong>决定</strong>
我们决定用 GraphQL 做产品搜索 API,建一个 /graphql 端点,用 Apollo Server 实现。客户端可以一次请求所需数据,减少端点维护。

<strong>后果</strong>
<strong>好处</strong>
- 客户端一次请求就能拿全数据。
- API 能适应新需求,不用改端点。
- 为公司试水 GraphQL,未来可能统一 API。

<strong>坏处</strong>
- 团队得学 GraphQL,初期设计和调试可能费时。
- 缓存和限流得重新搞,REST 的老办法不适用。

<strong>后续任务</strong>
- 给团队培训 GraphQL。
- 发布后密切监控性能。

<strong>替代方案</strong>
- 继续用 REST:要建多个端点,维护麻烦,没选。
- gRPC:性能好但对客户端要求高,放弃。

<strong>参考资料</strong>
- [GraphQL 官网]
- [Apollo Server 文档]


这个 ADR 清楚讲了为啥选 GraphQL、后果是啥,未来新人一看就懂。


5. 啥时候写 ADR?啥时候不用?
写 ADR 的场景:

  • 架构相关:影响系统结构、性能、依赖、接口等(比如选数据库、框架、部署方式)。
  • 高影响:改决定很麻烦或代价高(比如选了 SQL 数据库,改成 NoSQL 成本大)。
  • 有权衡:有多种选择,选哪个得掂量(比如买现成工具还是自己开发)。
  • 定策略:定了以后会影响很多设计(比如所有微服务都用 Kafka)。

不写 ADR 的场景:

  • 小决定:比如变量命名、小的代码优化。
  • 没得选的决定:比如必须升级某个库修安全漏洞。
  • 太细节的设计:具体算法实现、类结构,这些写在代码注释或设计文档里就行。

大白话建议:如果这个决定几年后有人会问“为啥这样搞?”,就写 ADR。写一份 ADR 也就半小时到一小时,省下未来查资料的时间。

6. 怎么整理和存 ADR?
存得好,ADR 才好用。

以下是最佳实践:

  • 存哪儿:
    • 代码库:放 docs/adr/,跟代码一起版本控制,开发方便找。
    • Wiki/文档平台:适合非开发人员看,但要保证有版本历史。
  • 命名:用编号+描述,比如 001-use-postgresql.md 或 use-postgresql-database.md。编号方便排序,描述让人一看就懂。
  • 文件夹结构:
    • 小项目:全放一个 adr/ 文件夹。
    • 大项目:按子系统分(比如 ui/、backend/)。
    • 建个 README.md 列出所有 ADR,方便快速浏览。
  • 版本控制:ADR 一旦接受就别改,改决定就写新 ADR,标记旧的为“被取代”。状态用“提议中”、“已接受”、“已废弃”标清楚。
  • 团队流程:把写 ADR 融入开发,比如:
    • 架构评审时问:“这决定要不要写 ADR?”
    • 代码审查时引用相关 ADR。
    • 新功能规划时留时间写 ADR。

例子 README:

# 架构决策日志
- <a href="0001-use-markdown-adr.md">ADR-0001</a> - 用 Markdown 记录架构决策
- <a href=
"0002-event-driven-architecture.md">ADR-0002</a> - 采用事件驱动架构
- <a href=
"0003-choose-kafka.md">ADR-0003</a> - 选 Kafka 做消息总线


7. 总结
ADR 是个轻量级工具,帮你记录为啥做了某个重要架构决定。它能:

  • 留住知识,防止新人一脸懵。
  • 让团队讨论更清晰,减少拍脑袋。
  • 帮你未来改设计时有据可依。
  • 避免查资料的麻烦,省时间防踩坑。

咋开始?

  • 找个简单模板,试着写一两个 ADR。
  • 放代码库或 Wiki 里,融入团队流程。
  • 从小决定开始,慢慢扩展。

最佳时机:项目刚开始时就写 ADR。其次是现在!别等以后,赶紧试试吧!