跳过正文

决策文档实用指南

· loading · loading ·
杰瑞德·林斯基
作者
杰瑞德·林斯基
居住在韩国首尔的新兴领导者和软件工程师

每个团队都在做决策,但大多数团队会忘记当初为什么这样决定。决策文档——不管你叫它ADR、RFC还是决策日志——通过记录重要选择的背景、备选方案和推理过程来解决这个问题。

本指南涵盖了何时该写决策文档、如何让它们真正发挥作用,以及可以直接拿来用的模板。


为什么决策文档很重要
#

1. 清晰度和透明度
#

决策文档提供了一种结构化的方式来阐明关键决策、考虑过的方案以及最终选择背后的理由。通过在统一的文档中记录这些信息,团队可以减少误解,让所有人保持一致。透明度能促进利益相关者之间的信任,因为它表明决策是经过深思熟虑、广泛参与后做出的。

2. 跨团队协调
#

大型项目通常涉及具有不同视角和优先级的跨职能团队。决策文档通过提供评估方案的清晰框架来帮助协调这些不同的群体。当各方都理解影响决策的因素时,更容易获得认同并齐心协力向前推进。

3. 避免返工和无休止的争论
#

你的团队重复讨论过多少次同样的问题?“为什么当初选了PostgreSQL而不是MongoDB?““API版本策略不是已经定了吗?“文档化决策能帮助团队避免反复讨论已经解决的问题。有了过去决策及其背景的清晰记录,团队可以专注于执行而不是重走老路。

4. 保存组织知识
#

项目可能持续数月甚至数年,期间团队成员会有进出。决策文档作为历史记录,保存了为什么选择某条路径的关键知识——不只是做了什么决定。这确保了即使人员变动也能保持连续性。

5. 问责制和所有权
#

通过明确决策者、贡献者和审批者,决策文档创造了问责制。每个人都知道自己的角色和责任,这让跟踪进度和确保执行变得更加容易。


什么时候该写决策文档
#

不是每个决策都需要正式文档。以下情况适合使用决策文档:

影响大的决策:

  • 技术栈选择(框架、数据库、云服务商)
  • 架构模式(微服务 vs 单体、事件驱动 vs 请求-响应)
  • 第三方供应商选型
  • 安全和合规方案

有长期影响的决策:

  • 外部系统依赖的API契约
  • 影响多个服务的数据模型设计
  • 对已有模式的破坏性变更

需要跨团队对齐的决策:

  • 影响多个团队或部门的变更
  • 需要非技术利益相关者认同的决策
  • 资源分配和优先级选择

Spike中产生的决策:

  • 当一个限时调研结束后,把发现和最终决策记录到正式文档中

可以跳过正式文档的情况:

  • 容易撤销的决策
  • 团队内部的实现细节
  • 对直接范围外影响很小的选择

决策文档的生命周期
#

了解决策文档在组织中的流转过程有助于最大化其效果:

┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│    草稿     │ ──► │    评审     │ ──► │    批准     │ ──► │    实施     │
│    提议     │     │   反馈      │     │    接受     │     │    完成     │
└─────────────┘     └─────────────┘     └─────────────┘     └─────────────┘
                    ┌─────────────┐
                    │   否决/     │
                    │   取代      │
                    └─────────────┘

草稿/提议: 作者创建初始文档,概述问题和潜在方案。

评审/反馈: 利益相关者审查文档、提出问题、建议替代方案。这个阶段至关重要——假设会被挑战,盲点会被发现。

批准/接受: 决策者(通常是技术负责人、架构师或产品负责人)做出最终决定。

实施/完成: 团队执行决策。更新文档以反映实施过程中的任何变化。

否决/取代: 有些决策在评审中被否决,有些随着情况变化而过时。明确标记这些状态以避免混淆。


如何写出有效的决策文档
#

从问题开始,而不是方案
#

一个常见的错误是直接跳到方案。相反,先明确说明:

  • 我们要解决什么问题?
  • 为什么这个问题现在很重要?
  • 如果不解决会怎样?

这种框架确保在讨论方案之前,所有人先对问题达成共识。

展示多个选项
#

即使你有强烈的偏好,也要记录至少2-3个替代方案。这体现了尽职调查,也帮助其他人理解为什么推荐的方案更好。每个选项应包含:

  • 简要描述
  • 优缺点
  • 工作量估算(粗略的T恤尺码就行:S/M/L/XL)
  • 风险和缓解策略

明确说明取舍
#

每个决策都涉及取舍。坦率地承认它们:

  • “我们选择了上市速度而不是架构纯洁性”
  • “我们接受了更高的运维复杂度以换取更好的可扩展性”
  • “我们优先考虑开发者体验而不是原始性能”

这些声明帮助未来的读者理解当时的背景和约束。

包含具体示例
#

抽象的讨论导致抽象的决策。用以下内容让文档更具体:

  • 展示方案如何实现的代码片段
  • 说明系统交互的图表
  • 指向Spike中概念验证实现的链接

设定明确的时间线
#

没有截止日期的决策会无限期拖延。明确指定:

  • 什么时候必须做出决策
  • 谁需要在什么时候之前提供意见
  • 如果决策延迟,什么会阻碍进度

示例:架构决策记录(ADR)
#

下面是一个实际的决策文档示例:

# ADR-001: API Authentication Strategy

**Status:** Accepted
**Date:** 2024-11-15
**Decision Maker:** Sarah Chen (Platform Architect)
**Contributors:** Backend Team, Security Team, Mobile Team

## Context

Our public API currently uses API keys for authentication. As we expand to
support third-party integrations and mobile apps, we need a more robust
authentication mechanism that supports:
- Token expiration and refresh
- Scoped permissions
- User-level authentication (not just service-level)

## Decision

We will implement OAuth 2.0 with JWT tokens for API authentication.

## Options Considered

### Option 1: OAuth 2.0 with JWT (Recommended)
**Description:** Industry-standard protocol with self-contained tokens

| Pros | Cons |
|------|------|
| Industry standard, well-documented | More complex initial implementation |
| Self-contained tokens reduce database lookups | Tokens cannot be revoked instantly |
| Broad library support | Requires refresh token management |

**Effort:** Medium (2-3 sprints)

### Option 2: Session-based Authentication
**Description:** Traditional server-side sessions with cookies

| Pros | Cons |
|------|------|
| Simple to implement | Not suitable for mobile apps |
| Easy to revoke sessions | Requires sticky sessions or shared session store |
| Familiar to most developers | Doesn't scale as well |

**Effort:** Small (1 sprint)

### Option 3: Custom Token System
**Description:** Build our own token-based authentication

| Pros | Cons |
|------|------|
| Fully customizable | Reinventing the wheel |
| No external dependencies | Security risks from custom implementation |

**Effort:** Large (4+ sprints)

## Consequences

- Mobile team can implement standard OAuth flows
- We'll need to set up a token refresh mechanism
- API documentation will need updates for OAuth flows
- Existing API key users will need a migration path (6-month deprecation)

## References

- [OAuth 2.0 RFC 6749](https://tools.ietf.org/html/rfc6749)
- Internal spike document: [Authentication Options Spike](/spikes/auth-spike-2024)
- Security team review: SEC-2024-042

决策文档模板
#

把这个模板作为你团队的起点:

属性详情
决策/议题名称[清晰、描述性的标题]
状态[草稿 / 评审中 / 已批准 / 已否决 / 已取代]
影响度[高 / 中 / 低]
负责人[推动决策的人]
决策者[拥有最终决定权的人]
截止日期[做出决策的截止时间]

问题描述
#

我们要解决什么问题?为什么重要?不采取行动的代价是什么?

背景
#

提供上下文、历史和相关细节。链接到相关文档、过去的决策或Spike结果。

约束条件
#

所有方案必须遵守哪些限制或要求?

  • 预算约束
  • 时间线要求
  • 技术约束(现有系统、技能储备)
  • 合规或安全要求

考虑的方案
#

选项描述优点缺点工作量风险
选项 1描述优点A,优点B缺点A,缺点BS/M/L/XL低/中/高
选项 2描述优点A,优点B缺点A,缺点BS/M/L/XL低/中/高
选项 3描述优点A,优点B缺点A,缺点BS/M/L/XL低/中/高

建议
#

说明推荐的选项,并总结在约束和取舍条件下为什么它是最佳选择。

决定
#

做出决定后记录最终决策。如果与建议不同,说明原因。

后果
#

这个决策有什么影响?需要哪些后续工作?

行动项
#

行动负责人截止日期
行动 1姓名日期
行动 2姓名日期

参考资料
#

相关文档、外部资源、Spike结果或过去决策的链接。


建设决策文档文化的建议
#

让文档容易被找到: 把决策文档存放在固定的位置——仓库中的专用文件夹、Wiki空间或文档系统。找不到就不会有人用。

保持轻量: 写起来要花好几天的决策文档不会有人写。从必要内容开始,在重要的地方补充细节。

在回顾会上复盘:回顾会中定期审视过去的决策。哪些决策效果好?哪些你会换个做法?这个反馈循环能改善未来的决策质量。

把决策和实现关联起来: 在代码注释、提交信息和Pull Request中引用决策文档。这在"为什么"和"做了什么"之间建立了可追溯性。

版本化和更新: 情况会变。当一个决策被取代时,不要删除旧文档——标记为已取代并链接到新决策。这样历史记录就保留下来了。


常见陷阱
#

分析瘫痪: 别让追求完美成为好的敌人。设定截止日期,用现有信息做出最好的决定,然后继续推进。大多数决策在需要时都可以重新审视。

走过场式审批: 如果评审总是没有实质性反馈就通过了,那这个流程就没有在创造价值。鼓励真正的批评和不同视角。

孤儿文档: 写了但从不执行的决策文档比没有文档还糟糕。确保决策能转化为行动。

过多细节: 决策文档应该解释"为什么"和"是什么”,而不是"怎么做”。实现细节应该放在技术规格书里,不是决策记录里。

忽视异议: 如果利益相关者不同意某个决策,记录他们的顾虑。即使决策不变,承认异议是一种尊重,也为未来的读者提供了重要的背景。


总结
#

决策文档不是额外负担——它们是在省时间。每一次"我们当初为什么选了X?“的对话因为有人能直接去读ADR而没有发生,就是实实在在节省下来的时间。

从你的下一个重要决策开始吧。写下来,哪怕写得粗糙也没关系。边做边完善流程。随着时间推移,你会积累起一份可搜索的记录,让未来的决策更快、新人上手更容易。


延伸阅读
#

本站相关文章:

外部资源: