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

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

帮我理解一下他的观点。

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

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

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

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


当前回答

“自文档化”代码背后的思想是,代码中的实际程序逻辑非常清楚,不仅可以向阅读代码的人解释代码在做什么,还可以向他们解释为什么要这样做。

在我看来,真正的自文档代码的想法是一个神话。代码可以告诉您正在发生的事情背后的逻辑,但它不能解释为什么要以某种方式完成,特别是如果有不止一种方法来解决问题。仅仅因为这个原因,它永远不能取代注释良好的代码。

其他回答

“自文档化”代码背后的思想是,代码中的实际程序逻辑非常清楚,不仅可以向阅读代码的人解释代码在做什么,还可以向他们解释为什么要这样做。

在我看来,真正的自文档代码的想法是一个神话。代码可以告诉您正在发生的事情背后的逻辑,但它不能解释为什么要以某种方式完成,特别是如果有不止一种方法来解决问题。仅仅因为这个原因,它永远不能取代注释良好的代码。

Self documenting code is code that is trivially easy to understand. Variable naming goes a long way to making code self documenting, but i find the best tactic is to break any complicated logic down into tiny little chunks and refactor that information into seperate methods with verbose and informative names. Then your complicated methods become simply a list of steps to be performed. The tiny private helper methods then are documented sufficiently by their own method name and the complicated methods are documented as a sequence of abstract steps to be performed. In practice this strategy cannot always be applied perfectly so comments are still very useful. Plus you should never completely abandon any tool which will help you write code that is easier to understand.

大多数文档/注释都是为了帮助未来的代码增强者/开发人员,从而使代码可维护。 通常情况下,我们会在稍后的时间回到我们的模块来添加新功能或优化。 在那个时候,通过简单地阅读注释来理解代码要比通过大量的断点来理解代码容易得多。 此外,我宁愿花时间思考新的逻辑,而不是破译现有的。

为什么代码之外的额外注释可能会更清晰,原因如下:

您正在查看的代码是自动生成的,因此对代码的任何编辑都可能在下次编译项目时失败 一个不太直接的实现被用来换取性能的提高(展开循环,为昂贵的计算创建查找表,等等)。

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

/**
 * 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;
 }

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