跳转至

ADR 格式

ADR 放在 docs/adr/,按顺序编号:0001-slug.md、0002-slug.md,依此类推。

docs/adr/ 目录按需创建:需要第一份 ADR 时才建。

模板

# {决策的简短标题}

{1–3 句话:背景是什么,决定了什么,为什么。}

就这些。一份 ADR 可以只有一段。价值在于记下做过这个决定、为什么,而不在于把各节填满。

可选的节

只在真有价值时才加。大多数 ADR 用不上。

  • Status frontmatter(proposed | accepted | deprecated | superseded by ADR-NNNN):决策会被重新审视时有用
  • Considered Options(考虑过的选项):只在被否掉的备选值得记住时
  • Consequences(后果):只在需要点出不明显的下游影响时

编号

扫一遍 docs/adr/,找到现有的最大编号,加一。

什么时候提出写 ADR

下面三条必须全部成立:

  1. 难以回退:日后改主意的代价不小
  2. 缺了上下文会让人意外:未来的读者看着代码会纳闷「他们到底为什么这么做?」
  3. 真实取舍的结果:确实有别的选项,出于具体理由选了其中一个

决策容易回退,就跳过:回退就是了。不让人意外,就没人会问为什么。没有真正的备选,除了「做了显而易见的事」也没什么可记。

哪些够格

  • 架构形态。「我们用 monorepo。」「写模型用事件溯源,读模型投影进 Postgres。」
  • 上下文之间的集成方式。「Ordering 和 Billing 之间走领域事件,不走同步 HTTP。」
  • 带锁定效应的技术选型。 数据库、消息总线、认证服务商、部署目标。不是每个库都算:只算那些换掉要花一个季度的。
  • 边界与范围的决定。「客户数据归 Customer 上下文所有;其他上下文只按 ID 引用。」明确说「不」的决定和说「是」的一样有价值。
  • 有意偏离显而易见的路。「我们手写 SQL、不用 ORM,因为 X。」凡是讲道理的读者会默认相反做法的地方都算。这类记录能拦住下一个工程师把有意为之的东西「修」掉。
  • 代码里看不到的约束。「合规要求不允许用 AWS。」「响应时间必须低于 200ms,因为合作方的 API 合同这么规定。」
  • 否掉的备选,当否掉的理由不明显时。 考虑过 GraphQL、出于微妙的原因选了 REST,就记下来;不然半年后又会有人提 GraphQL。