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

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

帮我理解一下他的观点。

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

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

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

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


当前回答

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.

其他回答

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

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

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

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

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

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

我忘了我从哪学来的,但是:

程序中的每一条评论都像是对读者的道歉。“很抱歉,我的代码太晦涩了,你看了都看不懂。”我们只需要接受我们并不完美,但要努力做到完美,在需要的时候道歉。

对我来说,阅读需要注释的代码就像阅读我不懂的语言的文本。我看到声明,但我不明白它是做什么的,也不明白为什么——我不得不看注释。我读了一个短语,我需要查字典来理解它的意思。

编写自记录其功能的代码通常很容易。要告诉你为什么这样做注释更合适,但即使在这里代码也可以更好。如果您在抽象的每一个层次上都理解您的系统,那么您应该尝试像这样组织代码

public Result whatYouWantToDo(){
  howYouDoItStep1();
  howYouDoItStep2();
  return resultOfWhatYouHavDone;
}

方法名反映了你的意图,方法体解释了你如何实现你的目标。 无论如何,你不能从书名中看出整本书,所以你的系统的主要抽象仍然必须被记录下来,还有复杂的算法、非平凡的方法契约和工件。

If the code that your colleague produc is really self-documented - lucky you and him. If you think that your colleagues code needs comments - it needs. Just open the most non-trivial place in it, read it once and see if you understood everything or not. If the code is self-documented - then you should. If not - ask your colleague a question about it, after he gives you an answer ask why that answer was not documented in comments or code beforehand. He can claim that code is self-document for such smart person as him, but he anyway has to respect other team members - if your tasks require understanding of his code and his code does not explain to you everything you need to understand - it needs comments.

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

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

' 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