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

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

帮我理解一下他的观点。

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

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

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

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


当前回答

在我看来,任何代码都应该是自记录的。在良好的、自文档化的代码中,您不必解释每一行,因为每个标识符(变量、方法、类)都有一个明确的语义名称。过多的注释实际上会使代码更难阅读(!),所以如果您的同事

为每个类、成员、类型和方法and编写文档注释(Doxygen、JavaDoc、XML注释等) 清楚地注释代码中没有自文档化AND的部分 为每个代码块写一个注释来解释意图,或者代码在更高抽象级别上做了什么(例如,找到所有大于10mb的文件,而不是遍历目录中的所有文件,测试文件大小是否大于10mb,如果为真则返回)

在我看来,他的代码和文档都很好。请注意,自文档化的代码并不意味着不应该有注释,而只是不应该有不必要的注释。然而,问题是,通过阅读代码(包括注释和文档注释)应该立即理解代码的功能和原因。如果“自文档化”代码比注释代码需要更长的时间来理解,那么它就不是真正的自文档化。

其他回答

我会扭转局面。

问问自己在他的代码中有什么不理解的,然后让他把这些记录下来。也许你也可以告诉我们一些。

自文档化代码是一种很好的实践,如果操作得当,可以轻松地传达代码的含义,而无需阅读太多注释。特别是在团队中的每个人都很好地理解该领域的情况下。

话虽如此,评论对于新手、测试人员或生成文档/帮助文件都非常有帮助。

自文档化代码+必要的注释将大大有助于跨团队的人员。

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

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

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.

既然这是关于注释和代码的,那么让我们来看一些实际的代码。比较下面的典型代码:

float a, b, c; a=9.81; b=5; c= .5*a*(b^2);

到这个显示正在执行的操作的自文档代码:

const float gravitationalForce = 9.81;
float timeInSeconds = 5;
float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2);

然后是这个文档代码,它更好地解释了为什么要这样做:

/* compute displacement with Newton's equation x = vₒt + ½at² */
const float gravitationalForce = 9.81;
float timeInSeconds = 5;
float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2);

最终版本的代码作为文档,不需要注释:

float computeDisplacement(float timeInSeconds) {
    const float gravitationalForce = 9.81;
    float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2);
    return displacement;
}

下面是一个糟糕评论风格的例子:

const float a = 9.81; //gravitational force
float b = 5; //time in seconds
float c = (1/2)*a*(b^2) //multiply the time and gravity together to get displacement.

在最后一个例子中,当变量应该被描述性地命名时,就会使用注释,当我们可以清楚地看到操作是什么时,就会总结操作的结果。无论如何,我更喜欢自文档化的第二个示例,也许这就是您的朋友所说的自文档化代码。

我会说,这取决于你所做的事情的背景。对我来说,在这种情况下,自编文档的代码可能就足够了,但是详细描述所做事情(在本例中是方程)背后的方法的注释也很有用。

我相信您应该始终努力实现自文档化代码,因为它确实使代码阅读变得更容易。然而,你也必须务实。

例如,我通常为每个类成员添加注释(为此我使用文档注释)。这描述了成员应该做什么,而不是如何做。我发现,当我阅读代码,特别是旧代码时,这有助于我快速记住成员是用来做什么的,我也发现这比阅读代码和解决它更容易,特别是当代码流跳跃相当多的时候。

这只是我的个人观点。我知道很多人在工作时根本没有评论,他们认为这没有问题。然而,我曾经问过某人关于他们六个月前写的一个方法,他们不得不思考几分钟来告诉我它到底是做什么的。如果方法是注释的,这不是问题。

最后,您必须记住,注释和代码一样都是系统的一部分。在重构和更改功能时,还必须更新注释。这是反对使用注释的一个论点,因为如果它们不正确,它们比无用更糟糕。