技术写作与文档2021codecatalog.org编辑精选
如何写出文档良好的代码——从示例中学习
Writing Well-Documented Code – Learn from Examples
导读
这篇博文用若干代码示例讲解如何写好文档化注释,核心争论是注释该写“做什么”还是“为什么”。评论区给出了大量反例和替代方案(更好的命名、测试、布尔变量),对任何需要写说明性文字的人都有借鉴价值:说明文字的价值在于补充读者无法从文本本身推断的信息。
可以直接用的写作要点
- 01
注释只写代码本身表达不出来的东西:写“为什么这样做”“什么情况下会这样”,不要复述代码已经在说的“做了什么”。
- 02
优先用精确的命名和结构承载信息:把注释里的条件含义提炼成描述性的布尔变量名,比在分支上贴注释更不容易过时。
- 03
把“说明”当作文档的一部分来经营:README 和解释某物为何存在的注释,长期价值远高于逐行解释实现细节。
- 04
写之前先想清楚读者在什么情境下会读到这段文字(例如凌晨三点排查故障),只提供他那时真正需要的信息。
HN 评论精选
注释不如好命名加测试可靠,注释应解释“为何存在”而非“做了什么”。
我觉得文中大部分示例都不够好。与其加注释,不如整体用更好的命名、命名清晰的私有方法,最重要的是配上结构良好的配套测试类来证明行为。凌晨三点抓狂调试别人的代码时,我实在不想读他对自己心理状态的评论。我被过时的注释误导过太多次,现在一般会打开 git blame 看注释是不是早于现有代码;而测试几乎从不说谎。解释“某物为何存在”的 README 或注释,通常比声称“它做了什么”的注释好得多。如果你连表达清晰的代码都写不出来,凭什么认为自己的英文会更好?
pcmoney查看英文原文
Personally I found most of those examples to be not great. I think they would be improved better names overall, more well named private methods and most importantly well structured companion test classes proving the behavior. I really dont want to read another developers comments on their mental state while I am feverishly debugging their code during a 3am page. The number of times I have been misled by an outdated comment. I generally open git blame to see if the comments predate any code now. Tests on the other hand almost never lie. Readmes or comments explaining why something exists vs what it allegedly does are generally much better. If you can’t write expressive code why would you assume your English is much better?
推荐 antirez 关于注释必要性的经典文章,反对“代码自解释”的空话。
说到源码注释,Redis 的作者 antirez 前阵子写过一篇很棒的文章,我至今仍推荐给那些随口说“代码本身就该能自我解释、不需要注释”的同事。
codethief查看英文原文
Speaking of source code comments, antirez (of Redis fame) wrote a fantastic article[0] about that topic some time ago and I still recommend it to colleagues whenever they make the hollow statement that "code should and can be intelligible on its own, without any comments". [0]: https://web.archive.org/web/20210226004600/http://antirez.com/news/124 (I still don't understand why he deleted his blog)
用描述性布尔变量名替代条件注释,更精确且不易过时。
第一个关于条件判断的例子,我更喜欢把注释里的“为什么”尽量化进布尔变量名。比如“我们仍有覆盖全部 token 请求的突发预算”这个分支,可以改写成 enoughBudgetForAllTokenRequests = self.one_time_burst >= tokens,再用它做判断。这种写法我见得不多,常见的是注释重复条件代码的“是什么”,而且往往看不出注释说的是条件还是整个分支。描述性的变量名让代码更容易扫读、更精确、也更不容易失效;复杂的条件可以拆成几个命名良好的布尔变量再组合起来,当然那些无法用简短变量名概括的部分还是要注释。
seanwilson查看英文原文
For the first example with conditions, I much prefer rolling the "why" of the comments into boolean variable names where possible e.g. // We still have burst budget for *all* tokens requests. if self.one_time_burst >= tokens { ... } else { // We still have burst budget for *some* of the tokens requests. becomes something like (I'm missing context but you get the idea): enoughBudgetForAllTokenRequests = self.one_time_burst >= tokens if enoughBudgetForAllTokenRequests ... else ... I don't see this often though. I see the commenting pattern a lot where the comment usually duplicates the "what" of the conditional code, and it's often ambiguous if the comment is talking about the condition or a whole branch. I think a descriptive variable makes the code easier to skim, it's more precise and less likely to become inaccurate. For a big complex conditional, you can break in up into several well-named boolean variables you compose together (but obviously comment the bits that can't be covered by a concise variable name).
不要复述代码,注释应补充预期情况与动机。
有些注释是冗余的。我现在习惯先把代码写成注释,再写实现。但像“若令牌桶容量或补充时间为 0,则禁用限流”这种注释和代码完全重复,毫无意义;我宁愿说明什么情况下它们会是 0,以及为什么为 0 时要禁用限流。而另一条注释就很棒:虽然乍看无法把代码和注释对应起来,但至少我明白了这段代码为什么存在——它说明了剩余未满足的令牌会从当前 budget 中扣除。
achenatx查看英文原文
some types of comments are redundant. These days I write my code as comments first and then write the code. But for example this one // If either token bucket capacity or refill time is 0, disable limiting. if size == 0 || complete_refill_time_ms == 0 { return None; } The comment is the same as the code. It is pointless. Instead I might say under what circumstances I expect them to be zero or why Im disabling limiting when they are zero. This one is great, though at first glance I cant relate the actual code to the comment, at least I understand why the code is there. // We still have burst budget for *some* of the tokens requests. // The tokens left unfulfilled will be consumed from current `self.budget`. tokens -= self.one_time_burst; self.one_time_burst = 0;
同类还值得读
编写更好文档的框架
A Framework for Writing Better Documentation
这是 Divio 的文档写作框架,把技术文档按「读者的目标」分成四类:教程(学习导向)、操作指南(问题导向)、参考(信息导向)、解释(理解导向)。
技术写作与文档2021 · 637 分 · 76 评4 条写作要点编辑精选写好一份设计文档
Writing a good design document
这篇 HN 帖子标题为《Writing a good design document》,主题是如何写好一份设计文档;对写作者来说,它值得作为技术写作和结构化说明文的参照。
技术写作与文档2025 · 581 分 · 147 评3 条写作要点编辑精选技术写作课程
Technical Writing Courses
这是 Google 官方免费技术写作课程(两门),讲受众定义、主动语态、短句、文档结构等基础方法。
技术写作与文档2020 · 571 分 · 73 评4 条写作要点编辑精选写出更好的错误信息
Write better error messages
这篇帖子讨论如何写出更好的错误信息,评论补充了开发者场景下的具体做法和真实反面案例。
技术写作与文档2022 · 566 分 · 253 评4 条写作要点编辑精选写一本技术书的经济账
The Economics of Writing a Technical Book
一位技术书作者拆解写书的真实经济账:版税收入往往远低于投入的时间成本。
技术写作与文档2018 · 519 分 · 149 评4 条写作要点编辑精选