我有一个同事,他坚持认为他的代码不需要注释,这是“自文档”。

我已经审阅了他的代码,虽然它比我看到的其他人编写的代码更清晰,但我仍然不同意自文档化代码与经过注释和文档化的代码一样完整和有用。

帮我理解一下他的观点。

什么是自文档代码 它真的能取代注释良好和文档化的代码吗 在某些情况下,它是否比有良好文档和注释的代码更好 是否存在代码不可能在没有注释的情况下自文档化的例子

也许这只是我自身的局限性,但我看不出这怎么能成为一种好的练习。

这并不是一个争论——请不要提出为什么注释良好并有文档记录的代码是高优先级的原因——有很多资源都表明了这一点,但它们对我的同行来说并没有说服力。我认为我需要更全面地了解他的观点,才能说服他。如果你有必要,可以提出一个新的问题,但不要在这里争论。

另外,那些反对自我记录代码的人——这主要是为了帮助我理解自我记录代码传播者的观点(即积极的方面)。


当前回答

自文档代码通常使用与代码所做的事情完全匹配的变量名,这样就很容易理解发生了什么

然而,这样的“自文档代码”永远不会取代注释。有时代码太复杂,自文档化代码是不够的,特别是在可维护性方面。

I once had a professor who was a firm believer in this theory In fact the best thing I ever remember him saying is "Comments are for sissies" It took all of us by surprise at first but it makes sense. However, the situation is that even though you may be able to understand what is going on in the code but someone who is less experienced that you may come behind you and not understand what is going on. This is when comments become important. I know many times that we do not believe they are important but there are very few cases where comments are unnecessary.

其他回答

首先,很高兴听到您同事的代码实际上比您见过的其他代码更清晰。这意味着他可能不会用“自记录”作为懒得注释代码的借口。

自文档代码是不需要自由文本注释的代码,以便知情的读者理解它在做什么。例如,这段代码是自记录的:

print "Hello, World!"

这也是:

factorial n = product [1..n]

这也是:

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)

现在,“知情读者”这个概念是非常主观和情境化的。如果你或其他人在遵循同事的代码方面遇到了困难,那么他最好重新评估一下他对博学读者的看法。为了调用代码自文档化,必须假定对所使用的语言和库有一定程度的熟悉。

我所见过的关于编写“自文档化代码”的最佳论据是,它避免了自由文本注释与代码编写时不一致的问题。最好的批评是,虽然代码可以描述它自己在做什么以及如何做,但它不能解释为什么某些事情会以某种方式完成。

首先,考虑下面的代码片段:

/**
 * Sets the value of foobar.
 *
 * @foobar is the new vaue of foobar.
 */
 public void setFoobar(Object foobar) {
     this.foobar = foobar;
 }

在这个例子中,每3行代码有5行注释。更糟糕的是,注释没有添加任何你在阅读代码时看不到的东西。如果你有10个这样的方法,你可能会得到“注释盲视”,没有注意到一个偏离模式的方法。

当然,更好的版本应该是:

/**
 * The serialization of the foobar object is used to synchronize the qux task.
 * The default value is unique instance, override if needed.
 */
 public void setFoobar(Object foobar) {
     this.foobar = foobar;
 }

不过,对于简单的代码,我更喜欢没有注释。意图和整体组织最好在代码之外的单独文档中解释。

我认为自记录代码是注释的一个很好的替代品。如果您需要注释来解释代码是如何或为什么是这样的,那么您应该修改函数或变量名以使其更具解释性。这可能取决于编码器是否会用注释或重命名一些变量和函数并重构代码来弥补不足。

但是,它并不能真正取代您的文档,因为文档是您提供给其他人用来解释如何使用您的系统的,而不是它是如何工作的。

编辑:我(可能还有其他所有人)应该有一个数字信号处理(DSP)应用程序应该很好地注释的规定。这主要是因为DSP应用程序本质上是2 for循环,提供了数组的值和添加/乘以/等等所说的值…要更改程序,您需要更改其中一个数组中的值…需要一些评论来说明在这种情况下你在做什么;)

在我工作的一家公司里,一个程序员把下面的文字粘在了她的显示器上。

“就像维护代码的人是一个知道你住在哪里的杀人狂一样,记录你的代码。”

以下是我对你的问题的最佳回答。

自文档代码是用类、方法、函数和变量名称清晰编写的代码,这些名称使其意图和函数易于理解。如果做得好,它就是文档。

它可以取代注释和文档完善的代码,但我很少见到它。很多时候,程序员认为他们已经足够好了,但是打倒他们的最好方法是开始问问题。如果他们不得不开始解释太多,那么他们的代码就不够清晰。您不应该阅读代码来了解它的功能。

在某些情况下,这样做会更好。如果代码又小又简单,那么添加文档可能会把事情弄得乱七八糟。

包含算法的代码应该包含注释。大多数时候,即使是最初的程序员也不记得几个月前他们在写一个长函数时到底在想什么。