站在读者的角度
我们在本书中所用的一个通用的技术是想象你的代码对于外人来讲看起来是什么样子的,这个人并不像你那样熟悉你的项目。这个技术对于发现什么地方需要注释尤其有用。
意料之中的提问
当别人读你的代码时,有些部分更可能让他们有这样的想法:“什么?为什么会这样?”你的工作就是要给这些部分加上注释。
例如,看看下面Clear()的定义:
大多数C++程序员看到这段代码时都会想:“为什么他不直接用data.clear()而是与一个空的向量交换?”实际上只有这样才能强制使向量真正地把内存归还给内存分配器。这不是一个众所周知的C++细节。起码要加上这样的注释:
公布可能的陷阱
当为一个函数或者类写文档时,可以问自己这样的问题:“这段代码有什么出人意料的地方?会不会被误用?”基本上就是说你需要“未雨绸缪”,预料到人们使用你的代码时可能会遇到的问题。
例如,假设你写了一个函数来向给定的用户发邮件:
这个函数的实现包括连接到外部邮件服务,这可能会花整整一秒,或者更久。可能有人在写Web应用时在不知情的情况下错误地在处理HTTP请求时调用这个函数。(这么做可能会导致他们的Web应用在邮件服务宕机时“挂起”。)
为了避免这种灾难,你应当为这个“实现细节”加上注释:
下面有另一个例子:假设你有一个函数FixBrokenHtml()用来尝试重写损坏的HTML,通过插入结束标记这样的方法:
这个函数运行得很好,但要警惕当有深嵌套而且不匹配的标记时它的运行时间会暴增。对于很差的HTML输入,该函数可能要运行几分钟。
与其让用户自己慢慢发现这一点,不如提前声明:
“全局观”注释
对于团队的新成员来讲,最难的事情之一就是理解“全局观”——类之间如何交互,数据如何在整个系统中流动,以及入口点在哪里。设计系统的人经常忘记给这些东西加注释,“只缘身在此山中”。
思考下面的场景:有新人刚刚加入你的团队,她坐在你旁边,而你需要让她熟悉代码库。
在你带领她浏览代码库时,你可能会指着某些文件或者类说这样的话:
·“这段代码把我们的业务逻辑与数据库粘在一起。任何应用层代码都不该直接使用它。”
·“这个类看上去很复杂,但它实际上只是个巧妙的缓存。它对系统中的其他部分一无所知。”
在一分钟的随意对话之后,你的新团队成员就知道得比她自己读源代码更多了。
这正是那种应该包含在高级别注释中的信息。
下面是一个文件级别注释的简单例子:
//这个文件包含一些辅助函数,为我们的文件系统提供了更便利的接口
//它处理了文件权限及其他基本的细节。
不要对于写庞大的正式文档这种想法不知所措。几句精心选择的话比什么都没有强。
总结性注释
就算在一个函数的内部,给“全局观”写注释也是个不错的主意。下面是一个例子,这段注释巧妙地总结了其后的低层代码:
没有这段注释,每行代码都有些谜团。(我知道这是在遍历all_customers……但是为什么要这么做?)
在包含几大块的长函数中这种总结性的注释尤其有用:
这些注释同时也是对于函数所做事情的总结,因此读者可以在深入了解细节之前就能得到该函数的主旨。(如果这些大段很容易分开,你可以直接把它们写成函数。正如我们前面提到的,好代码比有好注释的差代码要强。)
注释应该说明“做什么”、“为什么”还是“怎么做”?
你可能听说过这样的建议:“注释应该说明‘为什么这样做’而非‘做什么’(或者‘怎么做’)”。这虽然很容易记,但我们觉得这种说法太简单化,并且对于不同的人有不同的含义。
我们的建议是你可以做任何能帮助读者更容易理解代码的事。这可能也会包含对于“做什么”、“怎么做”或者“为什么”的注释(或者同时注释这三个方面)。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论