如何处理评论中的重言式?[关闭]


54

有时,我遇到的情况是我正在编写的部分代码是(或似乎是)不言而喻的,其名称基本上会作为注释重复:

class Example
{
    /// <summary>
    /// The location of the update.
    /// </summary>
    public Uri UpdateLocation { get; set; };
}

(C#示例,但请将该问题与语言无关)。

这样的评论是没有用的。我究竟做错了什么?是错误的名称选择吗?我怎样才能更好地评论这样的部分?我应该跳过诸如此类的评论吗?


8
注意:除非很清楚什么是“更新”,否则我认为“更新的位置”非常模糊。系统是否支持URL以外的其他URI?

34
return result # returns result
Lukas Stejskal'3

27
处理注释中的重言式的方法是处理注释中的重言式的方法。(这是评论。)
Rex Kerr

29
这实际上不是评论,而是以评论形式编写的文档。适用于API文档的规则与适用于内联代码注释的规则不同。
科迪·格雷

10
这只是不良API文档的示例,而不是代码注释。我对此类属性的C#XML格式应类似于“获取或设置可用于访问该对象的更新服务器的Uri”。
凯文·麦考密克

Answers:


13

在我从事的大多数项目中,没有足够的时间为每个班级成员写详细的评论。

这并不意味着没有时间发表评论。相反,有足够的时间进行重言式评论,以回击被评论内容的改写版本。它们作为一个很好的起点

尤其是考虑到Visual Studio使用了IntelliSense附带的注释,最好从有关该字段的一小部分信息开始:

class Example
{
    /// <summary>
    /// The location of the update.
    /// </summary>
    public Uri UpdateLocation { get; set; };
}

然后,当您继续编码时,如果您忘记UpdateLocation了更新发生的位置或更新发送到的位置,则必须重新访问代码。在这一点上,您应该添加其他信息:

class Example
{
    /// <summary>
    /// The Uri location where the update took place.
    /// </summary>
    public Uri UpdateLocation { get; set; };
}

如果其他程序员询问您有关某个字段的详细信息,请使用该信息更新注释:

应该Example.UpdateLocation使用哪种更新来存储?

class Example
{
    /// <summary>
    /// The Uri location where the Foo update took place.
    /// </summary>
    public Uri UpdateLocation { get; set; };
}

就像程序中有bug一样,好的注释也有需要迭代解决的bug。注释的目的是在六个月后重新访问代码时帮助您理解代码,并且不记得有关程序工作方式的任何信息。

就像编程一样,您的注释必须从某处开始。Hello World!当您练习写作和更新文档时,同义注释是注释的内容,您的起始文档将变得越来越有弹性。


+1是唯一实际提出其他评论的人;而不只是重言式的答案。
伊恩·博伊德

到目前为止,这实际上是最好的答案。
罗兰·特普

1
在我当前的项目中,由于缺少大型遗留代码库上的注释,我受到的打击超过了我所能想象的。作为作者的您认为这是一个显而易见的功能名称,您认为它是相当明显的功能,可能不像在三个月的时间内向另一位开发人员自我记录。有关方法,属性和字段的文档应该尝试将上下文放到更广阔的视野中,到目前为止,我已经看到了这个答案可以解释实现该目标的最佳过程。
罗兰·德普

1
@RolandTepp,我完全了解您来自哪里。我完全同意。我所看到的问题是,许多程序员认为注释和文档是在代码完成并准备好交付后发生的事情,而不是在开发过程中与代码一起发生的事情,这需要错误跟踪和支持时间以及其余的代码。
zzzzBov 2012年

54

注释绝不能重复您的代码。注释不应回答“ 如何? ”问题,而只能回答“ 为什么? ”和“ 什么? ”。为什么选择这样的算法,这里隐含的假设是什么(除非您的语言足够强大,可以使用类型系统,契约等来表达它),根本不这样做的原因是什么,等等。

我建议您看一下Literate编程实践以获取启发。


+1-这就是答案!我们不需要像“声明变量”意见“计数器加一”(一个循环)等
OZZ

因此在OP的示例中,什么是不错的评论?
stijn 2012年

4
@stijn,我不知道-代码中(显然)丢失了它。只有代码作者才知道其目的和局限性。
SK-logic

也许有些注释,例如//根据levelOfAttack(作为URL传递)更新了raiseShielders
woliveirajr 2012年

15
评论应该回答的最重要的问题是“ WTF?
naught101

53

注释应描述代码,而不是重复代码。该标题注释只是重复的。别说了。


17
+1:我想我理解您的意思,但我不同意您的说法:-)尽可能地,代码应该描述代码,而注释应该描述您的推理。
克拉莫伊(Kramii)恢复莫妮卡(Monica)2012年

3
@Kramii,不幸的是,即使您使用Agda进行编码,代码也无法描述该代码。没有一种语言能像自然语言那样强大和富有表现力。通常,您需要使用图表,图形,表格,复杂的公式来描述代码-如果没有适当的识字编程,这几乎是不可能的。
SK-logic

6
@ SK-logic:我不同意。长方法比起调用一系列有名的子例程的短方法要少自我描述。
克拉莫伊(Kramii)恢复莫妮卡(Monica)2012年

3
@Kramii,对不起,我看不到您不同意什么,以及您的评论与我所说的想法有何关系。我的观点是,您的代码应与很多信息一起提供,而代码本身完全是缺少的。您做出的决定背后的所有历史,所有与论文相关的参考,等等-没有语言元素可以表达这些东西。长方法与短方法/函数/子例程/在这里完全无关。
SK-logic

2
@ SK-logic,Kramii所说的意思是:“代码应该易于阅读和理解”,您提到的所有图形等都属于他所说的:“注释应描述您的推理”
Shahbaz

36

放他们出去!

通常,删除注释中表示的信息已存在于其他位置的注释是一种好习惯。如果您可以通过给它一个好名字清楚而明确地表达一种方法的目的,那么就无需评论

把它们放进去!

您的示例说明了此规则的两个例外:

首先,“ UpdateLocation”可能(取决于上下文)是不确定的。在这种情况下,您需要给它起一个更好的名字或提供注释以消除歧义。通常,改善名称是更好的选择,但这并不总是可能的(例如,在实现已发布的API时)。

其次,C#中的“ ///”表示用于自动生成文档的注释。IDE使用这些注释作为工具提示,并且有一些工具(Sandcastle)可以根据这些注释生成帮助文件等。这样,即使它们记录的方法已经具有描述性名称,也存在用于插入这些注释的参数。但是,即使到那时,许多有经验的开发人员也会对重复信息一无所知。决定因素应该是准备文档的人员的需求。


这是最好的答案。当您使用Example类并将鼠标悬停在该属性上时,您应该能够准确确定该属性将用于什么目的。
安迪

在这种情况下,我努力(而且常常失败),新增至少两种<remarks/><see/>因此在提供一些额外的内容。将<summary/>仍然是重复的,但整体的评论并非完全无用。
EarlNameless

20

我强烈不同意“不写评论”的回答。为什么?让我通过稍微改变一下示例来指出。

public Uri UpdateLocation ();

那么这个功能是做什么的:

  • 它是否返回“更新位置”?要么
  • 它会“更新”位置并返回新位置吗?

您可以看到,不加评论便有歧义。新来的人很容易犯错。

在您的示例中,它是一个属性,因此“获取/设置”方法表明第二个选项不正确,并且的确表示“更新位置”而不是“更新位置”。但是犯这个错误太容易了,尤其是在诸如“更新”之类的含糊词的情况下。安全起见。不要仅仅因为节省了几秒钟的时间而对新手感到困惑。


4
我认为没有人提倡根本不发表任何评论。大多数/所有人都在说“写适当的注释”,而UpdateLocation示例将在其中。
ozz 2012年

16
Uri UpdateLocation()将被代码审查拒绝,并更改为Uri GetUpdateLocation()void UpdateLocation()
avakar 2012年

4
@avakar:同意您的观点,但是由于这是C#属性(get和set会自动合成并具有相同的名称),GetUpdateLocation因此重命名为会导致类似的代码GetUpdateLocation = somelocationLocationOfUpdate将是一个更好的名称,这消除了歧义。基本问题是OP使用动词前缀而不是名词。假定前导动词表示方法的作用。
2012年

2
@DPD,“为一条线擦拭需要多少时间和精力”维护它需要花费多少精力?它浪费了多少屏幕空间?当它最终与代码不同步并开始使开发人员感到困惑时,会浪费多少时间?
avakar 2012年

1
该方法返回一个值,并具有动词短语名称。这就是问题。它应该有一个名词短语名称。例如“ Uri LocationOfUpdate()”。不是GetUpdateLocation,您说的是“您的GetLocation是什么?”?
ctrl-alt-delor 2012年

14

/// <summary>用于生成IntelliSense和API文档的文档

因此,如果这是一个面向公众的API,则即使该功能的目的对于读者来说不言而喻的,也应始终至少包含一个<summary>注释。

但是,这是规则的例外。通常,只记得干燥 (不要重复自己)


5

仅当您知道如何从诸如此类的事情中受益时,可以这样填写评论;否则,请擦拭它们。

对我来说,明显的好处是自动检查缺失的注释,我使用该检查来检测需要填写重要信息的代码。为此,我确实填充了一些占位符 -只是为了确保工具报告中不包含“错误警报”。

我认为总有办法避免公然重复。多年来,我一直在为像您这样的情况使用一对“模板填充 ”-主要是自描述性名称请参见上文

对于此特定示例,我将使用“自我描述类型”(假设不是通过擦除即可完成工作),例如:

class Example
{
    /// <summary>
    /// Self descriptive method name.
    /// </summary>
    public Uri UpdateLocation { get; set; };
}

我可以使用上述示例填充程序的示例是Javadoc注释,该注释需要专用字段来返回值,参数和异常。我经常发现,用单个摘要语句描述大多数甚至所有这些更好的方法,该方法针对提供的参数<describe parameters>返回<描述返回的内容>。在这种情况下,我用上面的简单内容填写必填字段,向读者提供摘要说明。


3

在考虑是否在代码段中添加注释时,我想问自己一个问题:我可以传达些什么,这可以帮助下一个人更好地理解代码的整体意图,以便他们可以更新,修复或更快,更可靠地扩展它?

有时,对于这个问题的正确答案是,在代码中没有什么可以添加的,因为您已经选择了使意图尽可能明显的名称和约定。这意味着您已经编写了可靠的自文档代码,并且在其中插入评论可能会减损您的工作。(请注意,冗余注释实际上会随着时间的流逝而减慢与真实代码的不同步,从而实际上会破坏代码的可靠性,从而使解读真实意图变得更加困难。

但是,在几乎所有程序和任何编程语言中,您都会遇到这样的问题,即原始程序员(由您自己)做出的某些关键概念和决定在代码中将不再明显。这几乎是不可避免的,因为优秀的程序员总是为将来编程—即,不仅要使程序一次运行,而且要使其所有许多将来的修复程序,版本,扩展和修改以及端口,以及谁知道该怎么做。可以正常工作。后一组目标要困难得多,并且需要更多的思考才能做好。这也是很难在大多数计算机语言,它更注重功能性,以良好表达-也就是在说什么做 为了使它令人满意,现在需要执行该程序的版本。

这是我的意思的简单示例。在大多数语言中,快速内联搜索小数据结构将具有足够的复杂性,以至于初次查看它的人可能不会立即识别出它是什么。这是一个很好的评论的机会,因为您可以添加一些有关代码意图的内容,以后的读者可能会立即发现它们对解密细节很有帮助。

相反,在诸如基于逻辑的语言Prolog之类的语言中,表达对一个小列表的搜索可能是如此的琐碎和简洁,以至于您可能添加的任何评论都只会是杂乱无章。因此,良好的评论必然取决于上下文。其中包括因素,例如您使用的语言的优势以及整个程序的上下文。

底线是:思考未来。问问自己,关于将来如何理解和修改程序,什么对您来说重要和显而易见。[1]

对于您的代码中那些真正可以自我记录的部分,注释只会增加噪音,并增加将来版本的一致性问题。因此,不要在此处添加它们。

但是对于您从几个选项中做出关键决定或代码本身过于复杂以至于其目的难以理解的那些部分,请以注释的形式添加您的特殊知识。在这种情况下,一个很好的评论是使将来的程序员知道必须保持相同的东西(顺便说一句,就是不变断言的概念)以及什么可以更改。


[1]不仅限于注释问题,还值得提出:如果您对将来的代码更改有非常清晰的认识,那么您可能应该考虑的不仅仅是注释并嵌入这些参数在代码本身中,因为与尝试使用注释将某些未知的未来人引向正确的方向相比,这几乎总是一种更可靠的方式来确保代码的未来版本的可靠性。同时,您还希望避免过于笼统,因为众所周知,人类不擅长预测未来,其中包括程序更改的未来。因此,请尝试在程序设计的各个级别上定义和捕获合理且经过充分验证的未来维度,但不要


3

在我自己的代码中,我经常将注释重言式留在原处,其中包括特别令人讨厌的内容,例如:

<?php
// return the result
return $result;
?>

...从解释的角度看,这显然对使代码更易于理解没有多大作用。

不过,在我看来,如果这些注释有助于保持语法荧光笔中颜色图案的视觉一致性那么它们仍然有价值。

我认为代码具有与英语非常相似的结构,即有“句子”和“段落”(即使“段落”可能完全由一个“句子”组成)。我通常在每个“段落”的上方都包含一个换行符和一个单行摘要。例如:

<?php
//get the id of the thing
$id = $_POST['id'];

//query the things out of the the database
$things = array();
$result = mysql_query("SELECT * FROM Things WHERE `id` = $id");
while ($row = mysql_fetch_assoc($result)) {
    //create a proper Thing object or whatever
    $things[] = new Thing($row);
}

//return the things
return $things;
?>

(忽略不完整的代码,SQL注入等。您会明白的。)

对我来说,最后的注释确实增加了代码的价值,仅因为它通过保持一致的着色方案有助于在视觉上将一个“段落”与另一个“段落”区分开。


我很难在这里在我的答案中突出显示语法。如果有一些编辑人员可以支持我并使其正常工作,我会非常感激,因为颜色对我的观点很重要。
克里斯·艾伦·莱恩


2

注释应用于执行以下操作之一。

  1. 供文档生成器获取的信息。这不能低估,这是非常重要的。
  2. 警告一段代码为何如此,以及其他注意事项。我已经处理过用2种编程语言编写的代码。其中的一个关键部分是要使两种语言具有相同的结构。告知用户如果他们更改此号码,还需要更改另一个号码,这将非常有帮助。
  3. 写笔记来解释为什么看起来如此奇怪的一段代码是这样的。如果您必须考虑如何使一段代码以特定的方式工作,而解决方案从一开始就不明显,则可能值得对您要执行的操作进行解释。
  4. 标记输入/输出(如果不清楚)。知道输入的内容以及输入的格式总是很高兴的。

注释不应用于执行以下操作:

  1. 说明非常明显的事情。我曾经看到过这样的旧代码:page=0; // Sets the page to 0。我认为任何有能力的人都可以解决。

2

我将删除重言式,但保留注释,我将通过提供示例值来注释属性和变量名称,以便清楚地理解用法:

property UpdateLocation:TUpdateLocation;  // url="http://x/y/3.2/upd.aspx",proto=http

现在,我确切地知道其中所包含的内容,并且从注释中,我已经清楚了如何使用它。


0

我会说这取决于评论的目的。

如果将它们用于生成文档以供构建该文档的团队使用(或者如果它们只是内联注释以说明问题),那么我认为将其排除在外是可以接受的。可以肯定地认为它是不言自明的;如果不是,附近还有其他团队成员可以解释。当然,如果事实证明,对于很多人来说这并不是不言而喻的,您应该添加它。

如果这些评论将为某个地理位置遥远的团队生成文档,那么我将把所有文档都放在那里。


0

我认为这个主题已经用“注释:反模式”或“注释是否有代码味道”的名称进行了广泛讨论。(一个例子)。

我倾向于同意评论应添加新信息而不是重复的大意。通过添加这样的琐碎注释,您违反了DRY,并降低了代码的信噪比。我倾向于找到高层次的注释来解释职责,背后的理由以及该类的示例用法,比按属性的注释(尤其是多余的注释)更有用。

就个人而言,在您的示例中,我将忽略掉注释(如果确实没有关于该属性的有用添加)。


0

如果您可以编写不需要注释的代码,那么您已经实现了编程必杀技!

代码需要的注释越少,代码就越好!


3
这是不可能的(而且永远不会)。总有离开的代码背后的东西很多-暗含的假设架构决策,数学变换的长链中的一个特定的算法结束了,等等
SK-逻辑

1
也许是“ Hello World!” 是程序员的必杀技……
naught101

:-}-这是很少实现的事情-关键是,如果您努力寻找可添加含义的注释,那么请对自己感到满意,这意味着您的代码正确!
詹姆斯·安德森

0

这样的评论是没有用的。我究竟做错了什么?

如果您已经知道该怎么UpdateLocation做,似乎就没用了。这里的“更新”是动词还是名词附加语?也就是说,这是否是更新位置的信息,还是更新的位置?也许可以从一个UpdateLocation显然是属性的事实推断出后者,但是更大的一点是,有时明确声明某些看起来很明显的内容并没有什么害处。


0

除了自动编译的文档外,代码还应自行记录,以便注释应仅在代码不足以自我记录的地方进行文档记录。


-1

“位置”很明显,但是“更新”可能有点含糊。如果您不能写出更好的名字,那么您可以在注释中提供更多详细信息吗?更新什么?我们为什么需要这个?有哪些假设(允许为null)?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.