2.8 KiB
2.8 KiB
ADR 格式
ADR 文件存放在 docs/adr/ 目录下,采用顺序编号:0001-slug.md、0002-slug.md,以此类推。
docs/adr/ 目录采用懒创建方式——仅在需要编写第一个 ADR 时才创建。
模板
# {决策的简短标题}
{1-3 句话:上下文是什么,我们做了什么决定,以及为什么。}
仅此而已。一条 ADR 可以只有一个段落。其价值在于记录做出了什么决定以及为什么——而不是填写各个章节。
可选章节
只有在确实能增加价值时才包含以下内容。大多数 ADR 不需要它们。
- Status 前置元数据(
proposed | accepted | deprecated | superseded by ADR-NNNN)——当决策被重新审视时很有用 - Considered Options(考虑过的方案)——仅当被否决的替代方案值得记住时
- Consequences(影响/后果)——仅当存在需要指出的非显而易见的后续影响时
编号
扫描 docs/adr/ 目录,找到当前最大编号并加一。
何时需要提交 ADR
以下三个条件必须全部满足:
- 难以逆转——后续改变主意的代价很大
- 脱离上下文会令人困惑——未来的读者看到代码后会想"他们到底为什么要这样做?"
- 是真正权衡后的结果——存在切实可行的替代方案,而你出于特定原因选择了其中一个
如果某个决策很容易逆转,那就跳过——反正你以后也会推翻它。如果不会令人困惑,那也没有人会追问原因。如果没有真正的替代方案,那么除了"我们做了显而易见的事"之外,也没有什么可记录的了。
哪些情况符合条件
- 架构形态。"我们使用了单体仓库。"写模型采用事件溯源,读模型投影到 Postgres。"
- 上下文之间的集成模式。"订单和计费通过领域事件通信,而非同步 HTTP。"
- 具有锁定效应的技术选型。数据库、消息总线、认证服务商、部署目标。不是每个库都要记录——只记录那些替换起来需要花一个季度的。
- 边界和范围决策。"客户数据归客户上下文所有;其他上下文仅通过 ID 引用。"明确说不的东西,与说是的东西同等重要。
- 刻意偏离常规路径的做法。"我们因 X 原因使用手写 SQL 而非 ORM。"任何合理读者可能会假设相反情况的事情。这样可以阻止后来的工程师去"修正"那些本就刻意为之的做法。
- 代码中不可见的约束。"由于合规要求,我们不能使用 AWS。""由于合作方 API 合约限制,响应时间必须低于 200ms。"
- 被否决的替代方案(否决理由非显而易见时)。如果你考虑过 GraphQL 但出于微妙原因选择了 REST,请记录下来——否则六个月后又会有人提议使用 GraphQL。