Skip to content

第 13 章:注释写什么

系列:软件设计的哲学 · 第 13/22 章
全书导读:00-overview.md


一句话总结

注释应描述从代码中看不出来的东西——分接口注释与实现注释,前者写契约与语义,后者写 tricky 细节与不变量,切忌复述代码。


核心观点浓缩

  • 接口注释:模块边界上,给调用方看——做什么、参数含义、返回值、异常、线程/性能预期
  • 实现注释:模块内部,给维护者看——为何选此算法、不变量、与相邻代码的隐含约定
  • 低层注释:单行或小块 tricky 逻辑旁,解释非显然的位运算、边界、并发
  • 高层注释:文件/类头,概括模块在系统中的角色与主要设计决策
  • 坏注释三例:复述代码、过时谎言、模糊废话(「处理数据」)
  • 重复文档(Doxygen 生成页)仍须源注释准确——生成器不会替你思考

关键概念 / 金句

类型应写不应写
接口前置条件、单位、是否幂等逐步描述实现步骤
实现为何不用更直观的写法把代码翻译成中文
低层此处的 off-by-one 原因显而易见的 i++

「若读者读注释后仍必须读实现才能安全调用,接口注释就失败了。」


本章在全书中的位置

承接第 12 章「为何要写」,本章给出内容规范。与第 14 章命名、第 15 章先写注释形成三角:注释定语义,命名消歧,设计阶段先写注释验接口。区分接口/实现注释,也是第 5 章信息隐藏的操作化——什么知识给调用方、什么留给内部,应体现在注释层级上。


个人思考与启发

扫描会话恢复逻辑里 resumeFromCache() 若只注释「恢复缓存」,新人仍会错用时机。改为写清「须在 initDevice 之后、startScan 之前调用;若缓存损坏则静默回退全量扫描」,误用率明显下降。实现注释里另补「与 rveScanDataManager 共享 LRU 槽位」一句,避免维护者误改缓存键而破坏会话模块边界。Review 时可对照注释清单逐项勾选,比通读实现高效。


与《程序员修炼之道》对照

  • 靠近代码的注释处理局部 trick;模块级文档对应本书接口/高层注释
  • 「编码规范」中的注释风格应区分 public API 与 internal——本书分类更细
  • 可逆性/不变量思想可写入实现注释,便于重构时校验
  • 自文档化代码口号若用来省接口注释,通常是在转嫁复杂度给调用方

重点与注意

重点:写注释前问「什么不能从代码直接看出?」——答案才是正文。
重点:接口注释写调用方视角;实现注释写维护者视角,勿混在 public 头文件。
注意:注释中的例子(输入/输出样例)极有价值,尤其解析与协议类代码。
注意:删代码时同步删注释;留 orphan 注释比无注释更害人。
注意:跨模块协议(JSON 字段、错误码)在双方接口注释中镜像描述,防漂移。


导航第 12 章 为何写注释 · 下一篇:第 14 章 命名

基于 VitePress 强力驱动 | 记录技术与生活