什么是自我记录代码,是否可以替换记录良好的代码?

时间:2008-10-16 15:24:55

标签: documentation comments

我有一位同事坚持认为他的代码不需要评论,而是“自我记录”。

我已经回顾了他的代码,虽然它比我见过其他代码生成的代码更清晰,但我仍然不同意自我编写代码的完整性和有用性以及评论和记录的代码。

帮助我理解他的观点。

  • 什么是自我记录代码
  • 它能否真正取代评论和记录良好的代码
  • 是否存在比记录良好和注释代码更好的情况
  • 是否存在代码无法在没有评论的情况下进行自我记录的示例

也许这只是我自己的局限,但我不知道它是如何成为一种好的做法。

这并不是一个争论 - 请不要提出为什么评论和记录良好的代码是高优先级的原因 - 有很多资源显示这一点,但它们并不能说服我的同行。我相信我需要更充分地理解他的观点来说服他。如果必须,请开始一个新问题,但不要在这里争论。

哇,快速反应!请阅读所有现有答案,并为答案提供评论,而不是添加新答案,除非您的答案与此处的其他答案完全不同。

此外,那些反对自我记录代码的人 - 这主要是为了帮助我理解自我记录代码福音传道者的观点(即积极方面)。如果你不留下话题,我希望别人会贬低你。

49 个答案:

答案 0 :(得分:368)

好吧,既然这是关于注释和代码的,那么让我们看看一些实际的代码。比较这个典型的代码:

float a, b, c; a=9.81; b=5; c= .5*a*(b^2);

这个自我记录的代码,显示正在做什么

const float gravitationalForce = 9.81;
float timeInSeconds = 5;
float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2);

然后是这个记录的代码,它更好地解释为什么正在完成:

/* compute displacement with Newton's equation x = vₒt + ½at² */
const float gravitationalForce = 9.81;
float timeInSeconds = 5;
float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2);

代码的最终版本作为文档,需要零注释:

float computeDisplacement(float timeInSeconds) {
    const float gravitationalForce = 9.81;
    float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2);
    return displacement;
}

以下是评论风格不佳的示例:

const float a = 9.81; //gravitational force
float b = 5; //time in seconds
float c = (1/2)*a*(b^2) //multiply the time and gravity together to get displacement.

在最后一个示例中,当变量应该被描述性地命名时使用注释,并且当我们可以清楚地看到操作是什么时,总结操作的结果。我希望任何一天都能有自己记录的第二个例子,也许这就是你的朋友在谈论自编代码时所说的话。

我会说这取决于你所做的事情。对我来说,在这种情况下,自我记录的代码可能就足够了,但是详细说明背后的方法背后的方法(在这个例子中,方程式)也很有用。

答案 1 :(得分:167)

在我看来,任何代码都应该是自我记录的。在良好的,自我记录的代码中,您不必解释每一行,因为每个标识符(变量,方法,类)都有一个清晰的语义名称。实际上有更多的评论实际上使得阅读代码更加困难(!),所以如果你的同事

  • 为每个类,成员,类型和方法编写文档注释(Doxygen,JavaDoc,XML注释等)
  • 清楚地评论代码的任何部分自我记录和
  • 为解释意图的每个代码块写一个注释,或者代码在更高的抽象级别上执行的操作(即查找大于10 MB的所有文件而不是循环遍历所有目录中的文件,测试文件大小是否大于10 MB,如果为真,则返回产生
在我看来,他的代码和文档很好。请注意,自我记录的代码意味着不应该有任何评论,而只是应该没有不必要的评论。但是,通过阅读代码(包括注释和文档注释),可以立即了解代码的作用和原因。如果“自我记录”代码比注释代码需要更长的时间来理解,那么它并不是真正的自我记录。

答案 2 :(得分:167)

代码本身始终是对代码执行情况的最新解释,但在我看来,它很难解释 intent ,这是最重要的评论方面。如果它写得正确,我们已经知道代码的 ,我们只需要知道为什么在地球上就可以了!

答案 3 :(得分:92)

有人曾说过

  

1)只为难以理解的代码写评论   2)尽量不要编写难以理解的代码。

答案 4 :(得分:36)

“自我记录”代码背后的想法是代码中的实际程序逻辑非常清楚,足以向任何阅读代码的人解释代码正在做什么但为什么要这样做。

在我看来,真正的自我记录代码的想法是一个神话。代码可以告诉你正在发生的事情背后的逻辑,但它无法解释为什么它以某种方式完成,特别是如果有多种方法来解决问题。仅凭这个原因,它永远不会取代评论良好的代码。

答案 5 :(得分:18)

我认为问一个特定的代码行是否是自我记录是相关的,但最后如果你不理解一段代码的结构和功能,那么大多数时候评论都没有帮助。以amdfan的“正确评论”代码为例:

/* compute displacement with Newton's equation x = v0t + ½at^2 */
const float gravitationalForce = 9.81;
float timeInSeconds = 5;
float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2);

此代码很好,但以下内容在大多数现代软件系统中都具有相同的信息,并明确承认使用牛顿计算是一种选择,如果其他一些物理范例更合适,可能会改变:

const float accelerationDueToGravity = 9.81;
float timeInSeconds = 5;
float displacement = NewtonianPhysics.CalculateDisplacement(accelerationDueToGravity, timeInSeconds);

根据我个人的经验,很少有“正常”的编码情况,你绝对需要评论。例如,您最终经常推出自己的算法?基本上所有其他事情都是构建系统的问题,这样编码人员就可以理解使用中的结构以及驱使系统使用这些特定结构的选择。

答案 6 :(得分:16)

我忘记了从哪里得到这个,但是:

  

程序中的每条评论都像对读者道歉。 “我很抱歉,我的代码非常透明,你无法通过查看来理解它”。我们必须接受我们并不完美,但要努力做到完美,并在我们需要的时候道歉。

答案 7 :(得分:14)

自我记录代码是“干”的一个很好的例子(不要重复自己)。不要在代码本身的注释中复制信息。

不是解释变量的用途,而是重命名变量。

不是解释代码的简短片段,而是将其提取到方法中并为其指定一个描述性名称(可能是评论文本的缩写版本)。

不是解释复杂测试的作用,而是将其提取到方法中并给它一个好名字。

在此之后,您最终得到的代码不需要那么多解释,它解释了自己,因此您应该删除仅在代码中重复信息的注释。

这并不意味着您根本没有任何评论,有些信息无法放入代码中,例如有关意图的信息(“为什么”)。在理想的情况下,代码和注释相互补充,每个都添加唯一的解释值而不会在另一个中复制信息。

答案 8 :(得分:13)

自我记录代码是一种很好的做法,如果正确完成,可以轻松传达代码的含义,而无需阅读太多注释。特别是在团队中的每个人都很好理解域名的情况下。

话虽如此,评论对新来者或测试人员或生成文档/帮助文件非常有帮助。

自我记录代码+必要的评论将大大有助于团队中的人们。

答案 9 :(得分:13)

首先,很高兴听到您的同事的代码实际上比您看到的其他代码更清晰。这意味着他可能不会使用“自我记录”作为懒得评论他的代码的借口。

自我记录代码是一种代码,它不需要自由文本注释,以便知情读者理解它在做什么。例如,这段代码是自我记录的:

print "Hello, World!"

这是这样的:

factorial n = product [1..n]

这是这样的:

from BeautifulSoup import BeautifulSoup, Tag

def replace_a_href_with_span(soup):
    links = soup.findAll("a")
    for link in links:
        tag = Tag(soup, "span", [("class", "looksLikeLink")])
        tag.contents = link.contents
        link.replaceWith(tag)

现在,这个“知情读者”的想法是非常主观和情境化的。如果您或其他任何人在跟踪您的同事代码时遇到问题,那么他应该重新评估他对知情读者的看法。必须假定对所使用的语言和库有一定程度的熟悉程度才能调用代码自我记录。

我所看到的编写“自我记录代码”的最佳论点是,它避免了自由文本评论的问题,因为它与编写代码不一致。最好的批评是,虽然代码可以描述 它自己在做什么,但它无法解释为什么以某种方式完成某些事情

答案 10 :(得分:9)

按顺序:

  • 自我记录代码是向读者明确表达意图的代码。
  • 不完全。评论总是有助于评论选择特定策略的为什么。但是,解释代码部分正在做什么的注释表明代码不够自我记录并且可能会使用一些重构...
  • 评论谎言并且过时了。代码总是告诉更有可能说实话。
  • 我从来没有见过一个案例,如果没有评论,代码的代码就不够清晰;但是,正如我之前所说,有时必须/有帮助在为什么上加上评论。
然而,重要的是要注意,真正的自我记录代码需要大量的自我和团队纪律。你必须学会​​更具声明性地编程,并且你必须非常谦虚并且避免使用“聪明”的代码来支持代码,这些代码非常明显,似乎任何人都可以编写它。

答案 11 :(得分:6)

当您阅读“自我记录代码”时, 你看到它在做什么, 但你不能总是猜到它为什么会这样做。

有大量的非编程限制 如业务逻辑,安全性,用户需求等。

当你进行维护时,那些backgorund信息变得非常重要。

只是我的一小撮盐......

答案 12 :(得分:6)

首先,请考虑以下代码段:

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

尽管如此,对于琐碎的代码,我更喜欢没有评论。在代码之外的单独文档中更好地解释了意图和整体组织。

答案 13 :(得分:5)

您是否听说过Donald Knuth的“WEB”项目来实施他的Literate Programming概念?它不仅仅是自我记录的代码;它更像是可以作为代码编译和执行的文档。我不知道今天使用了多少。

答案 14 :(得分:5)

您可能希望向您的同事指出的一件事是,无论他的代码如何自我记录,如果考虑并放弃其他替代方法,除非他用该信息评论代码,否则信息将会丢失。有时同样重要的是要知道替代方案被考虑以及为什么决定反对,代码注释最有可能随着时间的推移而存在。

答案 15 :(得分:5)

区别在于“什么”和“如何”。

  • 你应该记录例行程序的“内容”。
  • 除非特殊情况(例如,请参阅特定的算法文件),否则您不应记录“如何”执行此操作。这应该是自我记录的。

答案 16 :(得分:5)

在我工作的公司中,其中一位程序员将以下内容粘贴在她的显示器顶部。

“记录你的代码就像维护它的人是一个知道你住在哪里的同性恋疯子。”

答案 17 :(得分:4)

代码是自我记录的观点让我发疯。特定的代码行或子算法可能确实是自我文档化的,但它在更大的图片中的目的根本就不是。

我在一两个月前对此感到非常沮丧,我写了一篇完整的博客文章,描述了我的观点。 Post here

答案 18 :(得分:4)

我很惊讶没有人带来“Literate Programming”,这是由Donald E. Knuth于1981年开发的技术和“计算机程序设计艺术”的成名。

前提很简单:由于代码必须由人理解,并且编译器简单地抛弃注释,为什么不给每个人他们需要的东西 - 代码意图的完整文本描述,不受限制编程语言要求,适用于人类读者和编译器的纯代码。

Literate编程工具通过为文档提供特殊标记来实现此目的,该文档告诉工具哪些部分应该来源以及什么是文本。该程序稍后将源代码部分从文档中删除并组装代码文件。

我在网络上找到了一个示例:http://moonflare.com/code/select/select.nw或HTML版本http://moonflare.com/code/select/select.html

如果您可以在图书馆找到Knuth的书(Donald E. Knuth,Literate Programming,Stanford,California:语言和信息研究中心,1992,CSLI讲义,第27号),您应该阅读它

那是自我记录的代码,完整的推理和所有。甚至做了一个很好的文件, 其他一切都是写得很好的评论: - )

答案 19 :(得分:4)

我想为许多有效的答案提供一个更多的视角:

什么是源代码?什么是编程语言?

机器不需要源代码。他们很高兴跑步装配。编程语言对我们有利。我们不想写汇编。我们需要了解我们正在撰写的内容。编程就是编写代码。

你能读懂你写的吗?

源代码不是用人类语言编写的。已经尝试过(例如FORTRAN)但它并没有完全成功。

源代码不能含糊不清。这就是为什么我们必须在其中加入比文本更多的结构。文本仅适用于上下文,我们在使用文本时认为这是理所当然的。源代码中的上下文始终是explisit。在C#中思考“使用”。

大多数编程语言都有冗余,因此当我们不连贯时,编译器可以捕获我们。其他语言使用更多推理并尝试消除冗余。

计算机不需要类型名称,方法名称和变量名称。它们被我们用于参考。编译器不理解语义,这是我们使用的。

编程语言是人与机器之间的语言桥梁。它必须是我们可写的并且对它们可读。次要要求是它应该对我们可读。如果我们擅长允许并且擅长构造代码的语义,那么即使对我们来说,源代码也应该易于阅读。最好的代码不需要评论。

但是复杂性潜伏在每个项目中,你总是要决定把复杂性放在哪里,以及哪些骆驼可以吞下去。这些是使用评论的地方。

答案 20 :(得分:4)

我的观点写在这篇文章中:

The one single tip to document your code.

摘录:

  

而不是写很多评论   解释微妙的行为   你的计划,为什么不重组你的   逻辑,这样他们是不言而喻的?   而不是记录什么方法   正在做,为什么不选择一个明确的名字   那个方法?而不是标记   你的代码表明未完成的工作,   为什么不抛出一个   NotImplementedException()?代替   担心你的评论是否合理   对你的老板,你的礼貌足够礼貌   同事或任何人阅读代码,   为什么不停止担心   写它们吧?

     

您的代码越清晰越容易   它是维持它,扩展它,到   在未来版本上开展工作。该   你的代码越少越好,越少   需要有评论。更多   评论越高越好   维护成本。

答案 21 :(得分:4)

自我记录代码通常使用与代码正在完全匹配的变量名称,以便很容易理解正在发生的事情

但是,这种“自我记录代码”永远不会取代评论。有时代码太复杂,自编文档代码不够,特别是在可维护性方面。

我曾经有一位坚信这个理论的教授 事实上,我记得他最好的一句话是“评论是为了sissies” 起初我们所有人都感到惊讶,但这是有道理的 然而,情况是,即使您可能能够理解代码中发生了什么,但是经验不足的人可能会落后于您并且不了解正在发生的事情。这是评论变得重要的时候。我知道很多次我们认为它们不重要,但很少有人认为评论是不必要的。

答案 22 :(得分:3)

我认为 - 正如你们许多人所做的那样 - 要真正实现自我记录,代码需要表现出某种形式的意图。但我很惊讶没人提到BDD - Behavior Driven Development。部分想法是你有自动化测试(代码)来解释你的代码的意图,否则很难显而易见。

Good domain modeling 
+ good names (variabes, methods, classes) 
+ code examples (unit tests from use cases) 
= self documenting software 

答案 23 :(得分:3)

我认为自我记录代码是评论的一个很好的替代品。如果您需要注释来解释代码的方式或原因,那么您有一个函数或变量名称应该被修改为更具说明性。关于他是否会通过评论弥补不足或重命名一些变量和函数以及重构代码,可以归结为编码人员。

它无法真正取代您的文档,因为文档是您向其他人解释如何使用系统的内容,而不是如何使用系统。

编辑:我(可能还有其他所有人)可能应该对数字信号处理(DSP)应用程序进行非常好的评论。这主要是因为DSP应用程序本质上是2个用于数组值的循环和添加/乘法/等所述值...更改程序你改变其中一个数组中的值...需要几个评论来说明什么你正在那样做;)

答案 24 :(得分:3)

自我记录代码很容易选择退出问题,随着时间的推移代码,评论和文档的分歧。编写清晰的代码是一个规范因素(如果你对自己这么严格的话)。

对我来说,这些是我试图遵循的规则:

  • 代码应该简单明了 尽可能阅读。
  • 评论应该说明原因 我采取的设计决定,如:为什么 我使用这个算法,或 代码有限制,例如:确实如此 什么时候不工作......(这应该是 在合同/断言中处理 代码)(通常在函数/过程中)。
  • 文档应列出用法 (打电话给),方 效果,可能的返回值。它 可以使用代码从代码中提取 像jDoc或xmlDoc这样的工具。它 因此通常在外面 功能/程序,但接近 它描述的代码。

这意味着所有三种记录代码的方式都是紧密相连的,因此在代码更改时更有可能被更改,但不会与它们表达的内容重叠。

答案 25 :(得分:3)

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

我尽量让我的代码尽可能自我记录,但是当我几个月后再回来工作时,我确实需要阅读解释,以避免使用它进行散列。

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

但是很多代码确实需要注释才有意义,所以尽可能清楚地写出来,然后根据需要使用尽可能多的注释......

答案 26 :(得分:3)

所谓的自我记录代码的真正问题在于它传达了它实际所做的事情。虽然一些评论可能有助于某些人更好地理解代码(例如,算法步骤等),但它在某种程度上是多余的,我怀疑你会说服你的同行。

然而,在文档中真正重要的是代码中没有直接显示的东西:潜在的意图,假设,影响,限制等。

能够通过快速浏览确定代码执行X比确定代码不执行Y更容易。他必须记录Y ...

你可以向他展示一个看起来很好,很明显的代码示例,但实际上并没有涵盖输入的所有基础,例如,看看他是否找到了它。

答案 27 :(得分:2)

除了代码之外,额外注释可能更清晰的几个原因:

  • 您正在查看的代码是自动生成的,因此下次编译项目时可能会对代码进行任何修改
  • 为了提高性能而展开了一个不太直接的实现(展开循环,为昂贵的计算创建查找表等)。

答案 28 :(得分:2)

它将成为团队在其文档中所重视的全部内容。我建议记录为什么/意图而不是如何重要,这并不总是在自我记录代码中捕获。获取/设置没有这些是显而易见的 - 但计算,检索等应该表达的原因。

如果您来自不同国籍,请注意您团队的不同之处。用词的差异可能会影响方法的命名:

BisectionSearch

BinarySearch的

BinaryChop

这三种方法的贡献来自在3个不同大陆接受过培训的开发人员做同样的事情。只有通过阅读描述算法的注释,我们才能识别出库中的重复。

答案 29 :(得分:2)

//如果它没什么大不了的话,不要担心它。

//如果你一直在写评论,那么重要的评论将不会被看到

  • 方法参数注释:必须死掉。这是代码重复。

//参数应该是不言自明的。

  • WTF-factor想象力:包括我在内的某人会对此说WTF吗?

答案 30 :(得分:2)

大多数文档/评论用于协助未来的代码增强器/开发人员,从而使代码可维护。 通常情况下,我们最终会在稍后返回我们的模块以添加新功能或进行优化。 那时通过简单地阅读注释而不是逐步执行多个断点来理解代码会更容易。 此外,我宁愿花时间思考新的逻辑而不是破译现有的。

答案 31 :(得分:2)

对我来说,阅读需要评论的代码就像用我不知道的语言阅读文本。我看到声明,我不明白它的作用或原因 - 我必须看看评论。我读了一个短语,我需要查看字典以了解其含义。

通常很容易编写自我记录代码的代码。告诉你为什么它这样做更适合评论,但即使这里代码可以更好。如果你在每个抽象层次上理解你的系统,你应该尝试组织像

这样的代码
public Result whatYouWantToDo(){
  howYouDoItStep1();
  howYouDoItStep2();
  return resultOfWhatYouHavDone;
}

方法名称反映了您的意图,方法正文解释了您如何实现目标。 无论如何,你无法在其标题中讲述整本书,因此仍需要记录系统的主要抽象,以及复杂的算法,非平凡的方法契约和工件。

如果你的同事产品的代码真的是自我记录的 - 幸运的是你和他。 如果您认为您的同事代码需要评论 - 它需要。只需打开其中最重要的地方,阅读一次,看看你是否理解了一切。如果代码是自我记录的 - 那么你应该。如果不是 - 在他给你一个答案之后,问你的同事一个关于它的问题,请问为什么这个答案没有预先记录在评论或代码中。他可以声称代码是像他这样聪明人的自我文档,但无论如何他必须尊重其他团队成员 - 如果你的任务需要理解他的代码而他的代码没有向你解释你需要理解的一切 - 它需要评价。

答案 32 :(得分:1)

有人指出,评论应该捕捉意图,但我会更进一步。

我认为对于任何类别的问题,都有一个理想的(或几乎是这样的)词汇和语法来描述它,如果你只是问那些有这些问题的人来描述它们,你可以看到它(假设那个人可以想清楚)。

如果该词汇和语法很容易(通过将类,方法等定义)映射到计算机语言的代码中,那么该代码可以自我记录。此外,IMO是一种特定于域的语言。 (这是我对“陈述性”的粗略定义。)

如果问题没有完全映射到计算机代码上,那么你就需要将两者连接在一起。 IMO,这是评论的目的。

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

编辑:顺便说一句,我不赞成OOP方法,其中每个名词都成为一个类,每个动词都是一个方法。我已经看到了足够的英国媒体报道那种方式。

答案 33 :(得分:1)

我曾与一位即将向一家大公司出售金融套房的人合作过。他们坚持要他记录源代码,他为此制作了一个30多页的汇编程序例程并说'它是记录的,看起来' - 然后他翻到第13页并且有一个评论'一个一个地反击'。 伟大的产品,伟大的实施者,但......

无论如何,在我看来,上面的重要评论是设置背景。这个片段被描述为自我记录:

> from BeautifulSoup import
> BeautifulSoup, Tag def
> replace_a_href_with_span(soup):
>     links = soup.findAll("a")
>     for link in links:
>         tag = Tag(soup, "span", [("class", "looksLikeLink")])
>         tag.contents = link.contents
>         link.replaceWith(tag)

但是,我需要一个上下文来完全理解它。

答案 34 :(得分:1)

我认为他可能会得到的是,如果评论解释了代码的作用,那么应该重新编写代码以明确其意图是什么。这就是他自己记录代码的意思。通常这可能意味着简单地将长函数分解为具有描述性函数名称的逻辑小块。

这并不意味着不应该对代码进行评论。这意味着注释应该提供代码按原样编写的原因。

答案 35 :(得分:1)

良好的设计结构有助于指出某些功能适用于一般用途,有些功能适用于随机业务逻辑,即使您没有评论说“此功能是通用的”。

我们不应该忘记设计和规范文档。那些已经或至少应该有很多评论中不一定需要的文本。软件通常还有用户手册和其他描述文档,这些文档应该与程序的功能同步。如果用户必须从源代码而不是手册中找出软件的功能,情况就不是很好。因此,自我记录代码仍然不意味着已经记录了实际的软件。

考虑功能的可追溯性。当您拥有手册时,您应该能够跟踪源代码的功能并返回以获得更好的可维护性。手册和规范与编程无关,但它们与软件工程有关。软件越大,需要的工程越多。

答案 36 :(得分:1)

这里似乎非常混合的输入:)

我使用伪代码编程过程进行新的开发,这实际上使我的代码自我记录。我只在编写新代码然后对其进行扩展时才开始编写伪代码。我不是说这是最佳实践或类似的东西,我只是强调一种我觉得有用的技术,如果你知道你需要大量的代码文档,如果它去第三方,评论家等...它也在我写完一行代码之前偶尔会突出问题。

' 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

答案 37 :(得分:1)

来自非评论阵营的一些观点。

“评论良好”(详细)代码更难以阅读和理解。首先,只需要扫描更多文本。它增加了理解CodeBase的认知努力 - 非功能性文本占用了可用于显示代码的屏幕空间。

评论的另一个大问题是它们不可靠 - 特别是在较旧的代码库中,评论腐烂的速度比钻头更快。

然后当然还有写评论的努力。除了偶尔的一行澄清器,每次我开始评论代码时,我都会得到两种内疚感之一

  1. 此信息需要提供整体支持文档
  2. 我需要清理我的代码

答案 38 :(得分:1)

无论纯粹的自我记录代码是否可以实现,有些事情都会浮现在脑海中:

  • 永远不要让代码“令人惊讶”。 IE浏览器。不要使用愚蠢的宏来重新定义事物等。不要滥用操作符重载,不要试图聪明一点。
  • 在正确的位置拆分代码。使用适当的抽象。而不是内联滚动缓冲区(具有固定长度的缓冲区,两个指针在一端添加项目并在另一端删除),使用具有正确名称的抽象。
  • 保持低功能复杂性。如果它太长或太复杂,请尝试将其拆分为其他功能。

在实施特定的复杂算法时,添加描述算法的文档(或链接)。但在这种情况下,尽量避免不必要的复杂性和提高易读性,因为它太容易犯错误。

答案 39 :(得分:1)

我总是使用System.out来解释代码的作用。这样,您可以将其打印出来并在家中阅读:p

答案 40 :(得分:1)

这是一个很好的问题。它追溯到第一种允许评论的编程语言,我敢肯定。代码当然应该尽可能自我记录。指出明显的评论,应该被淘汰。使得更容易理解给定方法或代码段的意图,目的和用途的注释对于那些可能不太熟悉所讨论的语言或代码的人来说是非常宝贵的。允许生成API文档的结构化注释就是一个很好的例子。只是不要评论IF语句,该语句检查是否选中了复选框并告诉我您正在检查复选框是否已选中。在评论中重申显而易见的是我们宇宙中最糟糕的浪费击键。

//For example, the above text deals with what is a useful comment

答案 41 :(得分:1)

我相信您应该始终努力实现自我记录代码,因为它确实使代码更容易阅读。但是,你必须对事物务实。

例如,我通常会向每个类成员添加注释(我使用文档注释)。这描述了该成员应该做什么而不是如何做到这一点。我发现当我阅读代码,特别是旧代码时,这有助于我快速记住该成员的用途,并且我发现它比阅读代码并解决它更容易,特别是如果代码流程跳了很多

这只是我的意见。我知道有很多人在没有评论的情况下工作,并说他们觉得这没问题。然而,我曾向某人询问过他们六个月前所写的方法,他们不得不考虑几分钟来告诉我它究竟做了什么。如果方法被评论,这不是问题。

最后,您必须记住,评论与代码一样是系统的一部分。在您重构和更改功能时,您还必须更新您的评论。这是反对使用评论的一个论点,因为如果它们不正确,它们会比无用更糟糕。

答案 42 :(得分:1)

自我记录代码是愚蠢的。任何在数周,数月或喘息年后不得不重新访问其代码的人都知道(或者在我的情况下是几天)。 (或许推广这个想法的人仍然在耳后湿透了!?!?!)

使用有意义的,具有描述性的数据名称,智能地对您的代码进行分析,并留下自己的暗示,为什么你做了你所做的事情,你将过上更丰富,更充实的生活。

虽然......我读过曾经归因于比尔盖茨的一句话:“代码就是文档。”

去图。

答案 43 :(得分:1)

如果你的代码没有完全清楚而没有评论,那么就有改进代码的空间了。

我不是说“不要评论不清楚的代码”。我说“让你的代码清楚”。

如果您最终以某种方式不清楚代码,使用注释进行补偿。

答案 44 :(得分:1)

我认为这是适量文件的问题,而不是全部或全部。如果函数的参数名称很好,那么通常不必确切地说明它们是什么,例如char * CustomerName非常明显。如果对参数使用断言值范围,则不必记录这些范围。 IMO,文档应该涵盖一些不太明显的内容,因此需要一些解释,大多数代码都需要一些文档。就个人而言,在大多数情况下,我宁愿看一个给定函数如何工作而不是描述性文档的说明性示例。

文档文档可能是浪费时间,因为文档需要维护以保持代码库的最新状态。如果没有人会从阅读中受益,请不要制作它。

答案 45 :(得分:1)

我转过身来。

在他的代码中问自己你不理解的内容,然后让他记录下来。也许你也可以告诉我们一些。

答案 46 :(得分:1)

自我记录代码是非常容易理解的代码。变量命名对于使代码自我记录有很长的路要走,但我发现最好的策略是将任何复杂的逻辑分解成小块,并将这些信息重构为具有冗长和信息名称的单独方法。然后,您复杂的方法就变成了要执行的步骤列表。然后,通过他们自己的方法名称充分记录微小的私有帮助器方法,并将复杂的方法记录为要执行的一系列抽象步骤。在实践中,这种策略并不总能完美应用,因此评论仍然非常有用。此外,您永远不应完全放弃任何可以帮助您编写更易于理解的代码的工具。

答案 47 :(得分:1)

以下是我对问题的最佳答案。

自我记录代码是用类,方法,函数和变量名清楚地编写的代码,使其意图和功能易于理解。如果做得好,那就是文档。

可以替换经过充分评论和记录的代码,但我很少看到它。很多时候,程序员认为他们已经足够好了,但是最好的方法就是开始提问。如果他们必须开始解释太多,那么他们的代码就不够清楚了。您不必阅读代码就知道它的用途。

在某些情况下可能会更好。如果代码小而简单,那么你可能会通过添加文档来搞砸。

包含算法的代码应包含注释。大多数情况下,即使是最初的程序员也记不起几个月前他们写一个长函数时的想法。

答案 48 :(得分:0)

自我记录的代码是非常清晰的代码,不需要注释。我举一个小例子:

//iterate from 0 to 100
for(int i=0; i < 100; i++) {
   println i
}

评论很无用,因为代码很清楚。文档是一种很好的做法,但额外的文档可能会给代码添加不必要的噪音。你的同事需要知道的是,不是每个人都可以阅读其他代码并承认所有细节。

int calc(int a, int b) {
   return sqrt(a*a + b*b); //pythagoras theorem
}

如果没有评论,最后一段代码将难以破译。您可以想象其他更为人为的例子。