文档与注释:何时写、写什么

文档要么没有,要么过期。 新人问「这块怎么设计的」——文档是两年前的;改代码时没人记得更新 README;注释里写着「这里返回用户 ID」,实际已经改成返回邮箱了。文档和注释要写对地方、写对内容,并且随代码一起维护。本章讲文档类型(架构文档、API 文档、运行手册、决策记录)、注释的原则(解释为什么、而非重复代码)、以及文档即代码:版本控制与更新责任。

一、文档类型:架构、API、运行手册、决策记录

不同文档解决不同读者的不同问题;先分清「写给谁、回答什么」,再决定写什么、放在哪。

架构文档
描述系统由哪些部分组成、职责与依赖、关键约束与决策。给开发者、新人、以及做技术选型的人看。可配合架构图、分层说明、ADR 索引。
何时写:项目有分层/多服务/多模块时;随架构演进更新。
API 文档
接口的入参、出参、错误码、示例。给调用方(前端、合作方、其他服务)看。可用 OpenAPI/Swagger、代码内 docstring 生成,或独立维护。
何时写:有对外或跨团队接口时;接口变更时同步更新。
运行手册 / Runbook
部署、启停、配置、监控、常见故障与处理步骤。给运维、值班、上线的人看。写「怎么做」而不是「为什么」。
何时写:有部署与运维动作时;故障处理后可补充案例。
决策记录(ADR)
每条重要决策一篇:背景、决策、理由、后果。给后来人理解「当时为什么这么选」;架构章节已介绍过,这里强调要持续积累。
何时写:做技术选型、架构取舍、流程约定时;不事后补,当时就记。
四类常见文档及其读者与更新时机
文档类型一览

二、注释的原则:解释为什么、而非重复代码

代码里的注释应回答「为什么这么做」「在什么前提下成立」,而不是复述「这段在做什么」——后者应尽量用清晰的命名和结构表达,否则代码一改注释就过期、反而误导。复杂业务规则、非常规写法、历史坑、外部约束,适合用注释说明;简单逻辑能自解释就不写。

好的注释:解释为什么 / 前提

说明业务背景、约束或坑,读者能理解「为何这样写」。

// 订单金额满 100 才参与活动(运营 2024-01 约定)
const eligible = orderTotal >= 100;

差的注释:复述代码

没有信息量,代码一改注释就错。

// 判断是否大于等于 100
const eligible = orderTotal >= 100;
注释写「为什么」与前提,不写「在做什么」

公共 API(函数、类、接口)的文档注释(JSDoc、docstring 等)要写清:用途、参数、返回值、异常或错误码、简单示例。这样调用方和自动生成文档都能用;内部实现可简略,重点放在「契约」上。

三、文档即代码:版本控制与更新责任

文档即代码(Docs as Code)指把文档当代码一样管理:放在仓库里、用版本控制、用 PR 修改、和代码一起发布。这样文档和代码在同一套流程里,改代码的 PR 可以同时改文档,避免「代码改了、文档忘了」;谁改代码谁负责更新相关文档,责任清晰。

文档即代码的要点

  • 文档进仓库:架构说明、API 描述、Runbook、ADR 放在项目目录(如 docs/),随代码提交与分支演进。
  • 更新责任:谁改代码谁更新相关文档;PR 里若改了接口或行为,检查文档是否要同步改,并纳入 DoD 或 Review 清单。
  • 格式与生成:用 Markdown、AsciiDoc 等纯文本格式,便于 diff 与合并;API 文档可由代码或 OpenAPI 生成,减少手写不一致。
  • 单源与链接:能从一个地方生成多份产出(如同一份 OpenAPI 生成文档站和 SDK)就单源维护;文档之间用链接关联,避免复制粘贴大段内容。
文档与代码同仓库、同 PR,改代码的人负责更新文档

一句话: 文档分类型——架构、API、运行手册、ADR——各有读者与更新时机。注释解释「为什么」和前提,不重复代码;公共 API 用文档注释写清契约。文档即代码:文档进仓库、随版本控制、谁改代码谁更新文档,PR 与 Review 里一并检查,避免文档过期。

小贴士: 若文档和代码分开放(如文档在 Confluence、代码在 Git),至少在代码仓库里放一份「文档索引」或链接,并约定「改接口必须同步更新某处文档」,否则很容易脱节。

四、小结

文档类型:架构文档(结构·依赖)、API 文档(接口·参数)、运行手册(部署·排障)、决策记录 ADR(决策·理由),各有读者与更新时机。注释写「为什么」与前提,不复述代码;公共 API 写文档注释。文档即代码:文档进仓库、版本控制、谁改代码谁更新文档、PR 里检查,保证文档与代码同步。下一章讲测试策略与测试金字塔,从整体上把握测什么、测多少、谁测。