# 有用的代码注释

适用范围：新增、修改或审查代码注释时，保留读者无法从局部代码可靠恢复的契约、意图、约束和取舍。先遵循目标项目的注释语言与覆盖要求；本文不要求每个方法都写注释，也不允许用注释掩盖含糊命名或复杂控制流。

## 先选正确的表达方式

代码负责精确行为；名称、类型和接口让概念与可约束的条件可见；测试在行为被破坏时失败；注释解释代码难以表达的原因、业务背景和不可随意改变的约束。同一规则可同时需要测试和注释：测试守住结果，注释帮助维护者理解原因。

遇到难懂代码，先问能否用准确命名、清晰控制流或合适的边界解决；遇到可执行的不变量，先考虑测试。只有重要信息仍不能被这些方式充分表达，才写最短且可长期保持真实的注释。

## 写什么、放哪里

- **接口或方法契约**：调用者需要知道的输入单位、返回与失败语义、副作用、所有权或调用顺序，写在声明旁，不让调用者靠阅读实现猜测。
- **设计理由**：某种表示、算法或边界的选择及其取舍，写在拥有该决策的模块附近；避免叙述当前类和方法的游览路线。
- **局部原因与不变量**：某个顺序、检查或看似多余的步骤为何不能改变，紧贴相关操作，并说明违反后果。只写已经由需求、实现或测试证实的事实。
- **领域说明**：协议、计量或业务规则需要额外背景时，只教会读者理解当前实现所需的最小模型；大段或易变化的细节链接权威资料。
- **阅读路标**：多阶段流程确实难以一眼看清时，概括阶段目的和副作用，不逐句翻译代码。

一个概念需同步修改多处时，优先集中规则或让工具检查；暂时无法做到时，才在共同修改入口留精确的变更提示。不要用注释代替可执行约束。

## 项目要求方法注释时

按项目要求覆盖指定范围，包括简短方法，但只写实际责任。多阶段业务方法可从黑盒视角概括已确认的校验、计算、持久化和后续状态变化；只有实现确实保证时，才写事务、回滚、幂等、锁或失败语义。不要为凑覆盖率给每行代码配说明，也不要把要求扩展到无关旧代码。

## 核对与维护

写入前逐项核对事实来源；不知道设计理由时承认未知，不编造历史、性能或并发保证。改动行为时同步检查相邻注释；正常重构后就会失真的变量名、行号和实现步骤，不适合作为长期说明。

删除重复语法的注释和注释掉的旧实现，历史交给版本控制。延期事项需要说明具体限制、暂缓原因及何时重新处理；不要只留“以后优化”。保留仍然解释真实约束的旧注释，不因已有测试就机械删除。

## 参考

- [软件设计哲学：注释补充代码不能直接表达的知识](software-design-philosophy.md)。
- [Google Engineering Practices：代码审查关注点](https://google.github.io/eng-practices/review/reviewer/looking-for.html)：区分解释原因的注释与描述代码用途的接口文档。
