Files
2026-07-13 21:36:22 +08:00

2.8 KiB

ADR 格式

ADR 文件存放在 docs/adr/ 目录下,采用顺序编号:0001-slug.md0002-slug.md,以此类推。

docs/adr/ 目录采用懒创建方式——仅在需要编写第一个 ADR 时才创建。

模板

# {决策的简短标题}

{1-3 句话:上下文是什么,我们做了什么决定,以及为什么。}

仅此而已。一条 ADR 可以只有一个段落。其价值在于记录做出了什么决定以及为什么——而不是填写各个章节。

可选章节

只有在确实能增加价值时才包含以下内容。大多数 ADR 不需要它们。

  • Status 前置元数据(proposed | accepted | deprecated | superseded by ADR-NNNN)——当决策被重新审视时很有用
  • Considered Options(考虑过的方案)——仅当被否决的替代方案值得记住时
  • Consequences(影响/后果)——仅当存在需要指出的非显而易见的后续影响时

编号

扫描 docs/adr/ 目录,找到当前最大编号并加一。

何时需要提交 ADR

以下三个条件必须全部满足:

  1. 难以逆转——后续改变主意的代价很大
  2. 脱离上下文会令人困惑——未来的读者看到代码后会想"他们到底为什么要这样做?"
  3. 是真正权衡后的结果——存在切实可行的替代方案,而你出于特定原因选择了其中一个

如果某个决策很容易逆转,那就跳过——反正你以后也会推翻它。如果不会令人困惑,那也没有人会追问原因。如果没有真正的替代方案,那么除了"我们做了显而易见的事"之外,也没有什么可记录的了。

哪些情况符合条件

  • 架构形态。"我们使用了单体仓库。"写模型采用事件溯源,读模型投影到 Postgres。"
  • 上下文之间的集成模式。"订单和计费通过领域事件通信,而非同步 HTTP。"
  • 具有锁定效应的技术选型。数据库、消息总线、认证服务商、部署目标。不是每个库都要记录——只记录那些替换起来需要花一个季度的。
  • 边界和范围决策。"客户数据归客户上下文所有;其他上下文仅通过 ID 引用。"明确说的东西,与说的东西同等重要。
  • 刻意偏离常规路径的做法。"我们因 X 原因使用手写 SQL 而非 ORM。"任何合理读者可能会假设相反情况的事情。这样可以阻止后来的工程师去"修正"那些本就刻意为之的做法。
  • 代码中不可见的约束。"由于合规要求,我们不能使用 AWS。""由于合作方 API 合约限制,响应时间必须低于 200ms。"
  • 被否决的替代方案(否决理由非显而易见时)。如果你考虑过 GraphQL 但出于微妙原因选择了 REST,请记录下来——否则六个月后又会有人提议使用 GraphQL。