我有一个同事,他坚持认为他的代码不需要注释,这是“自文档”。
我已经审阅了他的代码,虽然它比我看到的其他人编写的代码更清晰,但我仍然不同意自文档化代码与经过注释和文档化的代码一样完整和有用。
帮我理解一下他的观点。
什么是自文档代码
它真的能取代注释良好和文档化的代码吗
在某些情况下,它是否比有良好文档和注释的代码更好
是否存在代码不可能在没有注释的情况下自文档化的例子
也许这只是我自身的局限性,但我看不出这怎么能成为一种好的练习。
这并不是一个争论——请不要提出为什么注释良好并有文档记录的代码是高优先级的原因——有很多资源都表明了这一点,但它们对我的同行来说并没有说服力。我认为我需要更全面地了解他的观点,才能说服他。如果你有必要,可以提出一个新的问题,但不要在这里争论。
另外,那些反对自我记录代码的人——这主要是为了帮助我理解自我记录代码传播者的观点(即积极的方面)。
我相信您应该始终努力实现自文档化代码,因为它确实使代码阅读变得更容易。然而,你也必须务实。
例如,我通常为每个类成员添加注释(为此我使用文档注释)。这描述了成员应该做什么,而不是如何做。我发现,当我阅读代码,特别是旧代码时,这有助于我快速记住成员是用来做什么的,我也发现这比阅读代码和解决它更容易,特别是当代码流跳跃相当多的时候。
这只是我的个人观点。我知道很多人在工作时根本没有评论,他们认为这没有问题。然而,我曾经问过某人关于他们六个月前写的一个方法,他们不得不思考几分钟来告诉我它到底是做什么的。如果方法是注释的,这不是问题。
最后,您必须记住,注释和代码一样都是系统的一部分。在重构和更改功能时,还必须更新注释。这是反对使用注释的一个论点,因为如果它们不正确,它们比无用更糟糕。
我曾经和一个家伙一起工作,他打算把金融套件卖给一家大公司。他们坚持让他记录源代码,他写了一个30多页的汇编程序,并说“这是有记录的,看”——然后他翻到第13页,有一条评论“bump counter by one”。
伟大的产品,伟大的实现者,但是……
无论如何,在我看来,上面的重要评论是为了设置上下文。这段代码是自记录的:
> from BeautifulSoup import
> BeautifulSoup, Tag def
> replace_a_href_with_span(soup):
> links = soup.findAll("a")
> for link in links:
> tag = Tag(soup, "span", [("class", "looksLikeLink")])
> tag.contents = link.contents
> link.replaceWith(tag)
但是,就我个人而言,需要一个背景来充分理解它。
自我记录代码是“DRY”(不要重复自己)的一个很好的例子。不要在注释中重复代码本身中的信息。
与其解释变量的用途,不如重命名变量。
与其解释一个简短的代码片段做什么,不如将其提取到一个方法中并给它一个描述性的名称(可能是注释文本的缩短版本)。
与其解释一个复杂的测试做什么,不如把它也提取到一个方法中,并给它起个好名字。
Etc.
在此之后,您将得到不需要太多解释的代码,它可以自行解释,因此您应该删除代码中只是重复信息的注释。
这并不意味着你完全没有注释,有一些信息你不能放入代码中,比如关于意图的信息(“为什么”)。在理想的情况下,代码和注释相互补充,每个注释都增加了独特的解释价值,而不会重复另一个注释中的信息。
不管纯粹的自文档代码是否可以实现,有一些事情是人们应该做的:
Never have code that is "surprising". Ie. don't use silly macro's to redefine things etc. Don't misuse operator overloading, don't try to be smart on this.
Split away code at the right point. Use proper abstractions. Instead of inlining a rolling buffer (a buffer with fixed length, with two pointers that gets items added at one end and removed at the other), use an abstraction with a proper name.
Keep function complexity low. If it gets too long or complex, try to split it out into other other functions.
当实现特定的复杂算法时,添加描述算法的文档(或链接)。但在这种情况下,要努力去除不必要的复杂性,增加易读性,因为很容易犯错误。