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

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

帮我理解一下他的观点。

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

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

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

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


当前回答

在编写数学代码时,我有时发现写一篇类似文章的长注释很有用,解释数学、代码使用的符号约定以及它们是如何组合在一起的。我们在这里讨论的是数百行文档。

我试着让我的代码尽可能地自文档化,但当我几个月后重新开始工作时,我确实需要阅读解释,以免把它弄得乱七八糟。

当然,这种极端的措施在大多数情况下是不必要的。我认为这个故事的寓意是:不同的代码需要不同数量的文档。有些代码可以写得很清楚,以至于不需要注释——所以要写得清楚,不要在那里使用注释!

但是很多代码确实需要注释才能有意义,所以写得越清楚越好,然后使用尽可能多的注释……

其他回答

代码本身总是对代码功能的最新解释,但在我看来,它很难解释意图,这是注释最重要的方面。如果代码写得很好,我们已经知道代码的功能,我们只需要知道它到底为什么这样做!

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

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

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

不管纯粹的自文档代码是否可以实现,有一些事情是人们应该做的:

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.

当实现特定的复杂算法时,添加描述算法的文档(或链接)。但在这种情况下,要努力去除不必要的复杂性,增加易读性,因为很容易犯错误。

已经提出的观点是,评论应该捕捉意图,但我想再深入一点。

我认为对于任何一类问题,都有一个理想的(或几乎是这样的)词汇和语法来描述它,如果你只是让遇到这类问题的人来描述它们(假设那个人能清晰地思考),你就能看到它。

如果词汇和语法可以很容易地(通过定义类、方法等)映射到计算机语言的代码上,那么这些代码可以是自文档化的。此外,IMO还创建了一种特定于领域的语言。(这就是我对“陈述性”的粗略定义。)

如果不能实现这个理想,如果问题不能直接映射到计算机代码上,那么就需要将两者联系起来。在我看来,这就是评论的目的。

这样,当问题发生变化时,您就可以找到相应的代码部分进行更改。

编辑:顺便说一下,我并不支持OOP方法论,即每个名词都变成一个类,每个动词都变成一个方法。我已经看过足够多的臃肿软件了。

这里的输入似乎非常复杂:)

我使用伪代码编程过程进行新的开发,这实际上使我的代码自文档化。我只在写新代码时才开始写伪代码,然后在上面扩展。我不是说这是最佳实践或类似的东西,我只是强调一个我认为有用的技巧,如果你知道你的代码需要大量的文档,如果它要交给第三方,审查者等等……它偶尔也会在我还没写一行代码的时候就给我指出一些问题。

' check database is available
  ' if it is then allow the procedure
  ' if it isnt roll back and tidy up 
' move onto something else

变成了;

' check database is available
  if checkDBStateResult(currentDB) = Open then 
     ' if it is then allow the procedure
          proc.Ok = True 
  else
     ' if it isnt roll back
          proc.Ok = False
          CleanUp()
  end if