it-swarm.cn

自我记录代码与注释代码

我进行了搜索,但未找到所需内容,如果已经提出此问题,请随时与我联系。

本月早些时候发表了这篇文章:

http://net.tutsplus.com/tutorials/php/why-youre-a-bad-php-programmer/

概括地说,如果您不编写注释,那么您就是一个糟糕的程序员。我个人的观点是,代码应具有描述性,并且除非注释不能自我描述,否则大多数情况下不需要注释。

在给出的例子中

// Get the extension off the image filename  
$pieces = explode('.', $image_name);  
$extension = array_pop($pieces);  

作者说此代码应该给出注释,我个人认为该代码应该是描述性的函数调用:

$extension = GetFileExtension($image_filename);

但是,在评论中实际上有人提出了这样的建议:

http://net.tutsplus.com/tutorials/php/why-youre-a-bad-php-programmer/comment-page-2/#comment-3571

作者回应说评论者是“其中的一个人”,即一个不好的程序员。

其他人对自我描述代码与注释代码有何看法?

22
Phill

我更喜欢编写自我记录代码。对此的指导是 清洁代码

当然,这并不意味着不应使用注释-它们具有其作用,但是恕我直言,您应该谨慎使用它们。 我在SO上的较早答案 更详细地解释了我对该主题的想法。

当然,正如@Niphra所指出的,始终值得仔细检查一下,我认为干净的东西是别人真正可以理解的。但是,这也是一个实践问题。根据我的想法,我回到uni时只是因为对所有代码实体使用了奇怪且有趣的名称,所以才编写了神秘的代码。在我的老师退回我的一项作业之前,礼貌地指出他无法弄清楚哪个模块是主要的:-)这是一个很好的课程,因此我一直致力于着力于编写自此以来更具可读性的代码。如今,我几乎没有收到队友的抱怨。

47
Péter Török

您不应该记录代码在做什么,但是应该记录它在做什么的原因。

没有多少命名技巧会暴露出为什么和为什么,因此您必须添加注释来解释各种代码的目的。

所有其他注释都可以安全删除。

66
biziclop

我实际上不相信自描述代码。可读性更高的代码可读性较差的代码,具体取决于语言,您的知识(作为原始作者),阅读该书的人的知识以及代码功能。但是不,仍然...应该在简短的评论中进行描述。

现在对我来说很清楚,我在该思维范围可能在一年内对我不太清楚,当时我正在考虑完全不同的事情并且需要使用再次输入代码。

因此,注释您的代码。当然,并不是每一行(天哪,不是),而是在函数/子例程/模块或特别棘手的部分上方加几行注释,并简要说明其作用。一两年后,您会感谢自己的。

38
Rook

幸运的是,这里讨论的两个阵营都在这里代表,并且都提到了赞成和反对的论点。

我相信两个阵营都有重叠的论据,并且实际上都同意其中的大多数观点,只是实现它们的方式略有不同。

重叠参数

  • 代码应可读。
  • 注释不应说出与代码完全相同的内容,而应在必要时提供进一步的见解。
  • 应该仔细考虑所有变量/函数名称,以便它们能很好地表示它们的作用。
  • 应避免重复代码。

现在,主要区别在于其中一些论点的重要性。

自描述代码

  • 注释可能会过时,因此请尽量减少使用它们,因为错误的注释比没有注释更糟糕。
  • 注释是代码的重复。可以用代码编写的所有内容都应该用代码编写。

更多评论

  • 注释比代码更具可读性。朴素的英语更能描述事物。

  • 普通代码通常会引起歧义,无论如何都必须对此进行注释。试图用代码描述这个,导致名字太长。此外,您将不断面对这些“额外”信息,而这些信息仅在您第一次遇到时才需要。

我相信两个阵营都有非常有效的论据,但是您不应该疯狂地追随一个阵营,因为它解决了一个问题。

为了演示,在 Clean Code 书中,代码被分解为许多较小的方法,这些方法仅被调用一次。创建方法的唯一原因是记录代码(并且简化了TDD)。结果是 功能地狱 。与原始代码相比,该代码的可读性较差,并且在重构时,并未考虑封装可重用的代码。

另一方面,您经常会在API的每个功能都被注释的地方看到它们,仅仅是因为“注释很好”。应该被评论的东西仍然没有。

19
Steven Jeuris

“对不起,但是你那个家伙。”

我不知道他为什么不喜欢评论:P

认真地说,编码是一门艺术,以至于人们无法如实地做出如此笼统的声明。有时您需要注释,有时需要更多更好的命名函数。通常都是。

将识字编程视为一种极端风格。

5
vegai

简短,更好和正确的答案

编写良好的“自记录代码”就是您所需要的想法,这是一种反模式,当它成为解释“为什么”的注释的例外时,应该死掉even。有一个神话,您总是可以为任何算法编写足够清晰的代码,以使任何程序员都可以浏览并获得它(或者它不需要重构或组织时间,而您没有)。更重要的是,经常写think他们编写清晰代码的程序员没有这样做。

注释仅应用于解释“为什么”的更好的答案是注释应:

  • 解释“为什么”(当然)
  • 仅在代码很复杂或目的不明确且不能或不值得进一步简化时,才在一行上解释“什么”
  • 解释代码块的“内容”,以加快理解速度并找到所需的内容

备份说明

人们错误地认为人们使用注释的唯一原因是解释一行代码的含义。事实是,注释代码的一个主要目的是使代码注释(quiicker)浏览代码并查找所需内容。当然,当我稍后返回代码或阅读别人的代码时,我可以阅读和理解编写良好的代码部分,但是阅读顶部的注释说该部分代码的作用是不是更快,更容易?如果不是我要的内容,请完全跳过它?如果您可以看一眼注释并理解整个功能,那么即使坐在那里,即使代码编写得很好,也为什么要坐在那里找出代码呢?这就是为什么我们对函数使用描述性名称-没有人说我不需要为函数使用描述性名称,因为有人可以浏览我编写清楚的代码来查看其功能。

例如,如果我正在查看其他人的功能,是否更容易逐行浏览代码以查看其功能,或者浏览整个功能中三个写得好的注释,以查看该功能的确切位置以及在哪里在做吗?

另一个反模式是过度使用函数来注释您的代码。命名函数是代码文档的重要组成部分,但有时程序员会将2-3行代码分开,这些代码永远不会在其他地方用于文档目的。为什么过度使用功能比过度使用注释更好?使用类似的功能与拥抱GOTO语句相同-它会创建意大利面条式的代码,可能会让人感到痛苦。

本质上,当您在企业环境中工作时,人们一直在共享代码,而人们却总是没有时间完善自己的代码,因此,一些好的注释可以节省大量的时间和挫败感。请记住,虽然您可能是一位能够以轻快的速度阅读代码的专家,但并非办公室中的每个人都可以。

3
dallin

嗯,您还必须记住一些对您而言显而易见或“自我记录”的东西,可能对其他人不是……也许对某些功能的了解较少的人。所以我对所有事情都发表评论。

2
user6791

好的,带有自我记录代码的是在该函数中,您会发现:

$pieces = explode('.', $image_name);  
$extension = array_pop($pieces);  

因为只有两行,所以当您具有函数名称时,这很容易解释。当事情变得更加复杂时,您要么必须用描述性名称将每行代码包装到一个函数中,要么使用注释在必要时

我从来不明白为什么它应该是一个或/或问题,而不是和/和。是的,使您的代码尽可能多地自我记录,是的,在本来很难理解的部分添加一些注释。

2
Joris Meys

注释和自记录的干净代码不同。代码就是关于how做事的。注释应覆盖why部分,无论您使用哪种语言,都无法用代码解释。另外,如果您的语言非常有限并且没有合同,没有静态规范甚至没有断言,则注释应涵盖代码的边界问题。

2
SK-logic

在这种情况下,很容易进行描述。但是我读了很多优秀的程序员编写的代码,他们认为他们的代码是自我记录的,对他们来说非常清楚的事情确实让我感到困惑。

$ extension = GetFileExtension($ image_name);

回到您的例子,我可以给它发送一组图像名称,还是仅拍摄一张图像?它支持任何类型的文件,还是仅支持其中一些类型?它将为我保护字符串,还是我必须这样做?如果文件类型不存在,它会通知我吗?

当然,我对此进行了扩展。但是我记得一个程序员,他相信audio_bandwidth和video_bandwidth是自我记录的名字;原来音频必须以字节表示,视频必须以千字节表示。花了很多时间弄清楚那个。

1
DistantEcho

一个不排除另一个。即使您的代码是自我注释的,但有时您可能仍需要常规注释来解释why您的自我注释代码可以完成其工作。

1
gablin

我不同意该文章,并在某种程度上同意你的看法。如果您使用好的方法名称,好的变量名称和小的方法来完成一件事情,那么代码应该很简单。

只是不要变得聪明,因为聪明的代码很糟糕,难以阅读和维护。关键字:maintain

我的意见是,评论应描述原因而不是原因。请记住,在这个假设的完美世界中,您的代码足够干净,可以轻松阅读,您不需要解释它在做什么,但是为什么选择这样做或那样做。

如果您使用的是源代码管理系统,则可以使用commit消息让所有人(和您自己)都知道在给定时间所做的事情,更重要的是为什么。

1
Sergio

我认为我们需要区分代码的文档表达性

在调试或检查代码时,您不是在读书。大多数时候,您只是想在方法之间跳转,并在脑海中快速建立联系,以基本了解运行时的状况。在此过程中,重要的不是代码的文档编制,而是表达性对代码签名至关重要。足够您可以立即识别它们并将它们添加到您自己的内部调用堆栈中。在这一点上,我们的大脑(至少,我的大脑是这样工作的;))倾向于将大的评论区视为噪音,而不是帮助。因此,单行注释,甚至更好,仅是自描述方法和对象名称就足够了。

如果您想“阅读特定类别或功能的书”,那么在单元测试中最好的选择是。经过精心设计的单元测试本质上是意图揭示的,比最厚的单元测试要多文档(即说明性的,详细的)注释块,因为它们包含1 /对此代码应该执行的操作的期望值和2 /根据实际代码检查这些期望值的能力。通过测试的可靠性比任何评论都高100倍,因为它证明了它所断言的真实性。

1
guillaume31

有些代码只是不自我记录,需要理解和测试该代码的同伴的一些评论。我认为,我下面的内容不足以理解它。

//
// iterative version
//
Node* ReverseList( Node ** List ) 
{

  Node *temp1 = *List;
  Node * temp2 = NULL;
  Node * temp3 = NULL;

  while ( temp1 )
  {
    *List = temp1; //set the head to last node 
    temp2= temp1->pNext; // save the next ptr in temp2
    temp1->pNext = temp3; // change next to privous
    temp3 = temp1;
    temp1 = temp2;
  }

  return *List;
}
1
Job

我通常喜欢编写自记录代码,并在注释不明确之处写注释,因为我认为大多数代码不会完全记录其本身。

1
Abbafei

您可能希望避免编写注释,就像您希望避免使用任何文档一样。对于编程语言本身,每个人(几乎)都使用相同的词汇和语法进行操作。

当您的应用程序用于特定领域时,可能很难让所有人都同意并/或建立通用词汇表。我们被教导要避免缩写和大量的行话,但我将其称为

息税折旧摊销前利润

并不是

权益折旧及摊销前的权益

如果您一个都不认识,那么您可能会不了解另一个。如果该公司的实施方式不常见,那么发表评论将对可能在该领域具有经验的下一个程序员有所帮助,但对这家特定公司没有帮助(这会使事情变得更加复杂。)。

1
JeffO

评论是必须的。因为在编写代码时,您的写作是为当前的需求而写的,同时也为将来必须阅读代码,弄清楚wtf,您在做什么,为什么做,然后如何对其进行修改的人们。

如果只是记住这一点,那么在编码/编程时?

我如何才能使其更容易理解和修改,以供将来正在使用此代码的编码人员使用,那么您会做得很好。失败了,您只是让其他人很难修改您的代码,并且别以为永远不会这样,那是罕见的...

在我的大部分工作中,我总是不得不修改其他人的代码,并且编写得最糟,文档很少。

因此,您认为代码文档本身就是一个习惯,就是不做尽职调查。

作为程序员,我们必须练习似乎完全是自律的自律。对于没有经验的程序员,但必须有习惯,以避免我们对他人代码的所有可怕体验。甚至是几个月后,看看我们自己的代码。

看看 http://thedailywtf.com 他们有很多幽默但真实的故事,关于程序员没有尽职调查的情况。

0
crosenblum

在大学里,我们被教导要用注释将英语的每一行代码改写一遍(可能只是让我们养成了解代码实际作用的习惯,而不是仅仅复制/粘贴某些内容并希望获得最好的结果)。

就我个人而言,我认为这会使您的代码杂乱无章,与仅是注释或代码相比,它使less易于阅读。我是C#编码人员,我一直做的唯一注释是“三斜杠”注释块,这些注释块被解释回IntelliSense文档。如果我对做某件事的特定方式感到特别内especially,或者看起来特别晦涩难懂,我将给出进一步的解释,仅此而已。

IMO:自记录代码是为变量和方法名称赋予有意义的上下文名称的代码,以便它们描述其用途。

0
James Love

如果您多次重新访问了代码,但仍未找到一种方法来使意图清楚的人知道该域。重写函数。毕竟不超过10-20行。如果更长,无论如何都要重写该功能,这就是为什么它不可读的原因之一:)

在不太可能的情况下,仍不清楚代码在做什么,您记得要向同行寻求帮助。好吧,我们都感谢您帮助不断发展的Linux,因为您编写的内核代码正确吗?如果没有冲洗,请从顶部重复:)

简而言之,不要写您在评论中的代码

0
Rune FS

查看Code Complete 2nd Edition,第128-129页。

抽象数据类型将使您免于这个难题。自我记录代码是必经之路。评论可能有用,但是

真实世界的实体,而不是底层的实现

您可以避免使用注释。

关于注释的一件事是您只编写了一次,但是在实现功能时看不到它们,只有在更改功能时才看到它们。

当注释由Delphi 2009+或JavaDoc的工作方式IDE)解释时,它们确实很有用,但这更多的是结构化标记语言,因此从某种意义上说,您正在编写文档,这非常聪明。

0
Peter Turner

我信奉这样的口号,即代码本身不会记录文档,因为您可能是世界上最好的程序员(Ada),但对所发生的事情一无所知,但是如果您记录原因并在短期内您的代码如何执行其功能,将来会为您自己和他人提供帮助。

0
Coyote21