← 技能图谱 · domain-modeling

ADR Format

ADR 的格式规范 — 属于 domain-modeling 技能

ADRs live in docs/adr/ and use sequential numbering: 0001-slug.md, 0002-slug.md, etc.

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

Create the docs/adr/ directory lazily — only when the first ADR is needed.

docs/adr/ 目录惰性创建——只在需要第一个 ADR 时才创建。

Template

Template

模板

# {Short title of the decision}

{1-3 sentences: what's the context, what did we decide, and why.}
# {决策的简短标题}

{1-3 句话:背景是什么、我们决定了什么、为什么。}

That's it. An ADR can be a single paragraph. The value is in recording that a decision was made and why — not in filling out sections.

就这样。一个 ADR 可以只是一个段落。价值在于记录做了决策以及为什么——而不是填满各个章节。

Optional sections

Optional sections

可选章节

Only include these when they add genuine value. Most ADRs won't need them.

只在对理解决策确实有价值时才包含这些。大部分 ADR 不需要它们。

  • Status frontmatter (proposed | accepted | deprecated | superseded by ADR-NNNN) — useful when decisions are revisited
  • Considered Options — only when the rejected alternatives are worth remembering
  • Consequences — only when non-obvious downstream effects need to be called out
  • Status 前置元数据(proposed | accepted | deprecated | superseded by ADR-NNNN)—— 当决策会被重新审视时有用
  • Considered Options —— 只有当被否决的备选方案值得记住时才包含
  • Consequences —— 只有当需要指出不明显的下游影响时才包含
Numbering

Numbering

编号

Scan docs/adr/ for the highest existing number and increment by one.

扫描 docs/adr/ 目录找到现有最高编号,加一。

When to offer an ADR

When to offer an ADR

何时提议创建 ADR

All three of these must be true:

  1. Hard to reverse — the cost of changing your mind later is meaningful
  2. Surprising without context — a future reader will look at the code and wonder "why on earth did they do it this way?"
  3. The result of a real trade-off — there were genuine alternatives and you picked one for specific reasons

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

  1. 难以撤销 —— 事后改变想法的成本很高
  2. 脱离上下文会令人费解 —— 未来的读者看到代码会疑惑"他们到底为什么这么做?"
  3. 真实权衡的结果 —— 存在真正的备选方案,你基于具体理由选择了其中之一

If a decision is easy to reverse, skip it — you'll just reverse it. If it's not surprising, nobody will wonder why. If there was no real alternative, there's nothing to record beyond "we did the obvious thing."

如果一个决策很容易撤销,跳过它——你将来会把它改掉的。如果不令人意外,没人会追问为什么。如果没有真正的备选方案,除了"我们做了显而易见的事"之外没什么可记录的。

What qualifies

What qualifies

哪些情况符合条件

  • Architectural shape. "We're using a monorepo." "The write model is event-sourced, the read model is projected into Postgres."
  • 架构形态。 "我们使用 monorepo。" "写模型是事件溯源,读模型投影到 Postgres。"
  • Integration patterns between contexts. "Ordering and Billing communicate via domain events, not synchronous HTTP."
  • 上下文之间的集成模式。 "Ordering 和 Billing 通过领域事件通信,而非同步 HTTP。"
  • Technology choices that carry lock-in. Database, message bus, auth provider, deployment target. Not every library — just the ones that would take a quarter to swap out.
  • 带有锁定效应的技术选型。 数据库、消息总线、认证提供商、部署目标。不是每个库——只是那些换掉需要一个季度的。
  • Boundary and scope decisions. "Customer data is owned by the Customer context; other contexts reference it by ID only." The explicit no-s are as valuable as the yes-s.
  • 边界和范围决策。 "客户数据由 Customer 上下文拥有;其他上下文仅通过 ID 引用。" 明确说"不"和说"是"同样有价值。
  • Deliberate deviations from the obvious path. "We're using manual SQL instead of an ORM because X." Anything where a reasonable reader would assume the opposite. These stop the next engineer from "fixing" something that was deliberate.
  • 有意偏离显而易见路径的选择。 "我们使用手写 SQL 而非 ORM,因为 X。" 任何合理的读者会假设相反方向的事情。这些能阻止下一位工程师"修复"某个有意的选择。
  • Constraints not visible in the code. "We can't use AWS because of compliance requirements." "Response times must be under 200ms because of the partner API contract."
  • 代码中不可见的约束。 "由于合规要求,我们不能使用 AWS。" "由于合作伙伴 API 合同,响应时间必须在 200ms 以内。"
  • Rejected alternatives when the rejection is non-obvious. If you considered GraphQL and picked REST for subtle reasons, record it — otherwise someone will suggest GraphQL again in six months.
  • 被否决的备选方案,当否决理由不显而易见时。 如果你考虑过 GraphQL 但因微妙的理由选择了 REST,记录下来——否则六个月后又会有人提议 GraphQL。