什么是自记录代码,它可以代替记录良好的代码吗?[关闭]


258

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

我已经阅读了他的代码,尽管它比我看到的其他代码更清晰,但我仍然不同意自我记录代码与注释和记录代码一样完整和有用。

帮我理解的观点。

  • 什么是自我记录代码
  • 它真的可以代替经过良好注释和记录的代码吗?
  • 在某些情况下,它比记录和注释好的代码更好吗?
  • 是否有一些示例,其中如果没有注释,代码可能无法自我记录

也许这只是我自己的局限性,但我不认为这是一种好的做法。

这并不意味着要争论-请不要提出充分注释和记录的代码具有较高优先级的原因-有很多资源可以证明这一点,但它们并不能说服我的同事。我相信我需要更充分地了解他的观点,才能说服他。如有必要,请提出一个新问题,但不要在这里争论。

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

另外,你们中那些反对自我记录代码的人-这主要是为了帮助我理解自我记录代码传播者的观点(即积极方面)。如果您不关注主题,我希望其他人会投票反对您。


118
你知道什么真正打动我吗?您不同意这个人,但您是想了解他,而不是向他发更多弹药。
kajaco

14
作为一个极端相反的案例,我有一位同事编写大量文档:在每个cpp文件中,她都包含一本手册,其中至少有数十页介绍了所提供功能的实现和用法。但是,她编写了灾难性的冗长而复杂的函数(具有8000行代码的单个函数),变量和函数的违反直觉的标识符等。与她相比,我要带一些人努力编写自我文档化的代码,这些代码在只要他的代码井井有条,并具有易于理解的小功能,便可以随时发表评论。
stinky472


1
总之,一个能够避免解释大部分的意见如何代码工作,并在这方面的代码自记录。但是通常还需要解释代码为什么以这种方式工作,例如,当您解决库中的限制时。您通常需要注释以解释原因。
Lutz Prechelt'2

2
我曾经与过分评论所有内容的人一起工作,但是通常会使用无用的注释,例如i++; // increment i-但没有解释为什么 i应该在函数中增加该点。
nnnnnn

Answers:


177

我认为,任何代码都应具有自记录功能。在良好的自记录代码中,您不必解释每一行,因为每个标识符(变量,方法,类)都有清晰的语义名称。注释多于必要,实际上会使阅读代码更难(!),因此如果您的同事

  • 为每个类,成员,类型和方法编写文档注释(Doxygen,JavaDoc,XML注释等),并且
  • 清楚地注释掉代码中没有自我记录的任何部分,并且
  • 为每个代码块写一个注释,以解释意图,或在更高抽象级别上执行该代码(例如,找到所有大于10 MB文件,而不是遍历目录中的所有文件,测试文件大小是否大于10) MB,如果为true,则返回收益

我认为他的代码和文档很好。请注意,自记录代码并不能意味着应该没有意见,但只应该有任何不必要的评论。事实是,通过阅读代码(包括注释和文档注释),应该可以立即了解代码的用途以及原因。如果“自记录”代码比注释代码需要更长的时间来理解,那么它并不是真正的自记录。



14
点nr。3应该是点nr的一部分。恕我直言,如果一个方法太复杂以至于它需要几个代码块的高度抽象注释,那么每个这样的代码块都应该是一个新方法。
Bjarke Freund-Hansen,2009年

10
+1表示“不代表不应该发表评论”,这似乎有些人的意见。
Skurmedel

4
仍然无需评论:公共静态Collection <File> filesGreaterThan(File path,int sizeInBytes);
Trylks 2014年

6
对我来说,一个很好的经验法则是,注释永远都不能解释代码正在做什么,而可以用来解释为什么这样做。换句话说,注释一个代码块以解释它为什么在那里,而不是它如何工作。如果您可以将该块分解为自己的清晰命名的方法,那就更好了。这就是自我记录代码的全部意义。
梅尔2014年

387

好吧,由于这是关于注释和代码的,所以让我们看一些实际的代码。比较以下典型代码:

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.

在最后一个示例中,当变量应被描述性地命名时使用注释,并且当我们清楚地看到操作是什么时,对操作的结果进行汇总。我更喜欢今天没有自我记录的第二个例子,也许这就是您的朋友在谈论自我记录的代码时谈论的话题。

我要说的是,这取决于您正在做的事情。对我来说,在这种情况下,自我记录的代码可能就足够了,但是详细说明背后完成工作背后的方法的注释(在此示例中,公式)也很有用。


73
那整个块实际上应该确实在一个具有描述性名称的函数中;)
workmad3

7
是的,我更容易理解函数displacementDueToGravity(int timeInSeconds,float gravitationalAcceleration = 9.81)。
克里斯蒂安罗莫

18
我在这里想念的一句话是:为什么要5秒?
John Nilsson

3
描述功能名称的另一投票。它没有给出方程本身,但我认为没有必要。
罗兰·佩希特尔

18
重力的单位是什么?变量名称可以添加的数量是有限制的。在某些时候,您必须解释您要做什么。通常这并不明显,这就是为什么需要注释代码的原因。说代码是自我记录的,这只是自我描述,这绝对是垃圾。
尼克

172

代码本身始终是代码功能的最新解释,但我认为很难解释意图(intent),这是注释最重要的方面。如果它的正确写入,我们已经知道什么代码的功能,我们只需要知道为什么地球上它吧!


同意 尽管有时即使最好的代码也可以隐藏其最终效果,但这可以通过在注释中回答“ why”来解决。如“为什么只用这种方式更改这5个变量?”
山姆·欧文

我的2分:[Unit,Spec,Behaviour,] Case是否对“ Why on Earth”有某种答案?然后,您可以阅读测试用例,并应了解原因。
琼克

2
我认为那些可以回答高层的原因,但是他们没有解释诸如“我将这个结构填充了这么多字节,以便当传输到一些晦涩的平台时它保持正确对齐”这样的事情。对于那些人,代码注释是保存机构知识的最佳方法。
tsellon

因此,您应该在给定代码本身的情况下明确意图。
Draemon

2
@tsellon,您的自动化规范可以告诉您这一点,而好代码是代码,它检查实施代码。因此,如果实现方式有所更改,则说明会破裂。那有多好?当实现代码不再执行注释中指定的内容时,这些注释会提醒您吗?
务实的军事评论家

96

曾经有人说

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


28
在编写代码时,让您理解的琐碎事实实际上可能很难让其他人以后理解,即使实际上某人几个月或几年之后也是如此。
安德斯·桑德维格

15
我经常发现我在星期五早上写的东西很难在星期一早上
弄乱

1
这导致我们“尝试不发表评论”
mustafabar

37

“自我记录”代码的思想是,代码中的实际程序逻辑非常清晰,足以向阅读该代码的任何人解释该代码在做什么,以及为什么这样做。

在我看来,真正的自我记录代码的想法是一个神话。该代码可以告诉您发生了什么的逻辑,但是无法解释为什么以某种方式进行,尤其是如果有多种方法来解决问题时,则尤其如此。仅出于这个原因,它就永远无法替换注释良好的代码。


1
恕我直言,块应该告诉你如何,函数名称应该告诉你为什么。只要你同时使用两者,你既传达意图和实施.... int GetBoundingBox() {return CalcContentDimensions() + this.padding + this.margin;}...
基本

19

我认为询问特定的代码行是否自我记录很重要,但是最后,如果您不了解代码片段的结构和功能,那么大多数时候注释将无济于事。以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);

以我自己的亲身经历,很少有绝对需要注释的“正常”编码情况。例如,您多久会滚动一次自己的算法?基本上,其他所有事情都与系统结构有关,以便编码人员可以理解所使用的结构以及促使系统使用这些特定结构的选择。


2
您需要更多支持,您的示例说明了为什么我们应该使用函数名称来记录意图。
Ape-in​​ago 2012年

16

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

程序中的每个注释都对读者道歉。“对不起,我的代码如此不透明,以至于您无法通过查看来理解它”。我们只需要接受自己不是完美的,而是努力做到完美,并在需要时就道歉。


26
垃圾。代码中的好注释绝对有其位置。以在两个同样正确的方法之间进行选择来解决问题为例。解释为什么选择一个方法而不是另一个方法的注释非常有意义,您永远无法从代码本身中获得该方法。
Scott Dorman

7
如果有两种ECORLLY CORRECT方法,那么为什么选择其中一种而不重要呢?
EBGreen

1
是的,同样正确并不意味着完全相同。在某些情况下,一种方法可能比另一种方法更快。
Ikke

因此,如果您的决策标准是速度,那么它们就不可能完全正确。我并不是说评论不好。只是因为它们是必需的,因为当前没有一种编程语言能如此清晰明确地使任何人都可以查看代码并立即知道代码的意图。
EBGreen

9
我不认为人们会像我一样理解这句话。我的意思是,您应该努力始终编写出如此清晰的代码,以至于无需注释,但您必须接受这是一种在现实中永远行不通的理想。
EBGreen

14

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

自我记录代码是不需要自由文本注释的代码,以使有知识的读者了解它在做什么。例如,这段代码是自我记录的:

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)

现在,这种“知情读者”的想法是非常主观和情境的。如果您或任何其他人在遵循同事的代码时遇到麻烦,那么他会很好地重新评估他对有见识的读者的想法。为了调用代码自记录,必须假定对所使用的语言和库有一定程度的了解。

我看到的关于编写“自文档代码”的最佳论据是,它避免了自由文本评论与编写的代码不一致的问题。最好的批评是,虽然代码可以描述什么如何它是由自己做,它不能解释为什么事情正在做一定的方式。


14

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

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

与其解释简短的代码片段的作用,不如将其提取到方法中并为其提供描述性名称(也许是注释文本的缩写)。

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

等等。

在此之后,您最终得到不需要太多解释的代码,它本身就进行了解释,因此您应该删除仅重复代码中信息的注释。

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


4
一个例外:糟糕的程序员。我已经看到评论说代码正在做某事,而事实并非如此。然后我问自己:我应该修改代码还是注释?
古格

您不能在Objective-C中击败方法名称。:)

13

自记录代码是一种很好的做法,如果做得好,可以轻松传达代码的含义,而无需阅读过多注释。尤其是在团队中每个人都了解该域的情况下。

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

自我记录的代码+必要的注释将对帮助团队中的人们大有帮助。


9

为了:

  • 自记录代码是向读者明确表达其意图的代码。
  • 不是完全。评论总是有助于评论为什么选择了特定策略。但是,解释一段代码正在做什么的注释表示该代码不能自我记录,可以使用一些重构。
  • 评论撒谎,变得过时。代码能说出真相。
  • 我从未见过这样的情况:没有注释就无法使代码的内容变得足够清楚。但是,就像我前面说的,有时需要/有益的,包括在评论为什么

但是,需要注意的是,真正的自我记录代码需要大量的自我约束和团队约束。您必须学习以声明性方式进行编程,并且必须谦虚并避免使用“聪明”的代码,而要使用显而易见的代码,以至于似乎有人可以编写它。


我会在这里添加一个尼特镐。代码并不总是“讲真话”。代码可能会产生误导,并且很容易混淆其意图。例如,一个错误命名的变量或方法可能与过期的注释一样多。
楔子

方法名称可以撒谎,也可以过期。
Calmarius 2014年

7

当您阅读“自记录代码”时,您会看到它在做什么,但是您不能总是猜测为什么它会以这种特定方式工作。

有大量非编程约束,例如业务逻辑,安全性,用户需求等。

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

只是我的盐...


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

不过,对于平凡的代码,我更喜欢不加注释。在代码之外的单独文档中,可以更好地解释意图和整体组织。


记录获取者和设置者似乎微不足道,但是我认为在没有用处的评论与根本没有任何评论之间有一个快乐的中介。Javadoc注释的主要目的是告知无法或不愿意查看该方法中的代码的人。
James McMahon

6

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

  • 您应该记录例程的“做什么”。
  • 除非有特殊情况(例如,请参见特定的算法论文),否则您不应记录“如何”执行该操作。那应该是自我证明的。

强烈反对。例程的名称应该很明显。它的实现方式应该从实现代码中显而易见。为什么要按原样编写实现,应予以记录
安东尼·曼宁·富兰克林

5

您可能希望向同事指出的一件事是,无论他的代码如何自我记录,如果考虑并放弃其他替代方法,除非他用该信息注释代码,否则信息将丢失。有时,同样重要的是要知道是否考虑了替代方案,以及为何选择替代方案,并且代码注释最有可能随着时间的流逝而存续。


您以此为准,最终将在代码库中编写教科书;-)我同意非显而易见的决定。
ddimitrov

@ddimitrov,这是一个很好的观察。但是,正如您所说的那样,非显而易见的决定(通常都是那些确实需要文档的决定),这是一个好习惯。
Onorio Catenacci

记录编写的代码!:)
Tony

5

在我工作的一家公司中,一位程序员在她的显示器顶部贴了以下东西。

“像维护代码的人一样记录代码,这是一个知道你住在哪里的疯子。”


4

自我记录代码通常使用与代码所执行的操作完全匹配的变量名,这样很容易理解正在发生的事情

但是,此类“自记录代码”将永远不会替换注释。有时代码太复杂,而自记录代码是不够的,尤其是在可维护性方面。

我曾经有一位教授坚信这一理论,实际上,我记得他说过的最好的一句话是“评论是对娘娘腔的评价”,
这让我们所有人一开始感到惊讶,但这是有道理的。
但是,这种情况是,即使您可能能够理解代码中正在发生的事情,但是经验不足的人却可能会落后于您而无法理解正在发生的事情。这是评论变得重要的时候。我知道很多时候我们不认为它们很重要,但是在极少数情况下不需要评论。


然后重构它,直到更清晰为止。我坚信代码中没有什么可以说得很清楚的。
Tigraine

4
除了为什么要选择特定的实现,算法或公式而不是另一个同样正确的方案。您永远无法描述为什么要在代码中做出选择,仅描述那个选择是什么。
Scott Dorman

1
@scott:您可以将这两个选项放在一个更大的类下,而不要在另一个选项上添加有关...的评论,等等。
Ape-in​​ago 2012年

4

我很惊讶没有人带来“ 文字编程 ”,这是TeX的Donald E. Knuth在1981年开发的一种技术,并以“计算机编程的艺术”而闻名。

前提很简单:由于代码必须由人来理解,而注释只是被编译器丢弃,所以为什么不给每个人他们所需的东西-代码意图的完整文本描述,不受编程语言要求的束缚,供人类读者阅读,纯代码则用于编译器。

精简编程工具通过为文档提供特殊的标记来做到这一点,该标记告诉工具哪些部分应为来源,什么是文本。该程序随后将源代码部分从文档中剥离出来,并组装一个代码文件。

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

如果您可以在图书馆中找到Knuth的书(Donald E. Knuth,Literate Programming,加利福尼亚州斯坦福:语言和信息研究中心,1992年,CSLI讲义,第27号),则应该阅读。

那是自我记录的代码,包括推理和全部内容。即使是一个很好的文档,其他所有内容也都写得很好:-)


实际上,这与自我记录代码相反。文字为人类,代码为机器。代码应该是哪种语言?组装当然。人类不需要阅读它,对吗?他们只需要写它!
古格

4

我想对许多有效答案提供另一种观点:

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

这些机器不需要源代码。他们很高兴参加大会。编程语言对我们有利。我们不想编写汇编。我们需要了解我们在写什么。编程是关于编写代码。

您应该能够阅读所写内容吗?

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

源代码不能有歧义。这就是为什么我们必须在文本中添加更多结构的原因。文本仅与上下文一起使用,当我们使用文本时,这是理所当然的。源代码中的上下文始终是明确的。在C#中考虑“使用”。

大多数编程语言都具有冗余性,因此当我们不一致时,编译器可以抓住我们。其他语言使用更多推论,并尝试消除这种冗余。

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

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

但是复杂性潜伏在每个项目中,您始终必须决定放置复杂性的位置以及吞下哪些骆驼。这些是使用评论的地方。


3

自我记录代码很容易解决,随着时间的推移,代码,注释和文档会有所不同。编写清晰的代码(如果您严格要求自己)是一个训练因素。

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

  • 代码应尽可能简单明了。
  • 注释应给出我做出设计决策的原因,例如:为什么使用此算法,或代码具有局限性,例如:在...时不起作用(这应在代码中以合同/声明方式处理)(通常在功能/过程中)。
  • 文档应列出用法(调用转换),副作用,可能的返回值。可以使用jDoc或xmlDoc之类的工具从代码中提取它。因此,它通常在函数/过程之外,但接近于它描述的代码。

这意味着所有三种记录代码的方式都紧密地联系在一起,因此,当代码更改时,更可能会更改它们,但它们所表达的内容不会重叠。


3

所谓的自我记录代码的真正问题在于它传达了其实际功能。尽管有些注释可以帮助某人更好地理解代码(例如算法步骤等),但在某种程度上是多余的,我怀疑您是否会说服您的同伴。

但是,文档中真正重要的是那些不能从代码中直接看出来的东西:潜在意图,假设,影响,限制等。

能够一眼确定代码是否X的能力比确定代码不能Y的方法容易得多。他必须记录Y ...

您可以向他展示一个看起来不错,很明显但实际上并未涵盖输入的所有基础的代码示例,然后看看他是否找到了它。


3

我认为自我记录代码可以很好地代替注释。如果您需要注释来解释代码的方式或原因,那么您应该对函数或变量名进行修改以使其更具解释性。不过,由编码人员决定是否用注释来弥补不足,还是重命名一些变量和函数以及重构代码。

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

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


因此,函数或变量名将提供足够清晰的上下文,以解释为什么在给定两种或更多种同样正确的解决问题的方式的情况下,为什么选择一种实现而不是另一种实现?
Scott Dorman

3

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

我试图使我的代码尽可能地自我记录,但是几个月后我再次使用它时,我确实需要阅读说明,以免产生任何哈希值。

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

但是很多代码确实需要注释才有意义,因此请尽可能清晰地编写注释,然后根据需要使用尽可能多的注释...


3

我要像你们中的许多人一样争辩说,要真正实现自我记录,代码需要表现出某种形式的意图。但是我感到惊讶的是没有人提到BDD- 行为驱动开发。想法的一部分是,您可以通过自动化测试(代码)来解释代码的意图,否则很难将其弄清楚。

良好的领域建模 
+好名字(变量,方法,类) 
+代码示例(用例中的单元测试) 
=自我记录软件 

2

除了代码之外,其他注释可能更清楚的几个原因:

  • 您正在查看的代码是自动生成的,因此,下次编译项目时,对该代码的任何编辑可能会被破坏
  • 权衡了一个不那么直接的实现,以提高性能(展开循环,创建查找表以进行昂贵的计算等)。

2

这将是团队在其文档中所重视的一切。我建议记录原因/意图而非重要性,而在自我记录代码中并不总是如此。获取/设置这些都不是显而易见的-但是应该表达出计算,检索等原因。

如果您来自不同国籍,也请注意团队中的差异。用法上的差异会影响方法的命名:

二等分搜索

二进制搜索

BinaryChop

这三种方法由在3个不同大洲受过培训的开发人员提供的功能相同。只有阅读了描述算法的注释,我们才能在库中识别出重复项。


2

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

通常很容易编写可自我记录其功能的代码。要告诉您为什么这样做,注释更合适,但是即使在这里代码也可以更好。如果您了解每个抽象级别的系统,则应尝试组织代码,例如

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

方法名称反映了您的意图,方法主体解释了您如何实现目标。无论如何,您都无法以书名来讲述整本书,因此仍然必须记录系统的主要抽象以及复杂的算法,非平凡的方法契约和工件。

如果您的同事生产的代码确实是自我记录的,那么您和他很幸运。如果您认为您的同事代码需要注释,则需要注释。只需打开其中最平凡的地方,阅读一次,看看您是否了解所有内容。如果代码是自我记录的-那么您应该这样做。如果不是,请向您的同事提出一个问题,在他给您答案后,请问为什么该答案未事先记录在注释或代码中。他可以声称代码对于他这样的聪明人来说是自我证明,但是无论如何,他必须尊重其他团队成员-如果您的任务需要理解他的代码,而他的代码不能向您解释您需要了解的所有内容-它需要注释。


2

大多数文档/注释都用于协助将来的代码增强器/开发人员,从而使代码可维护。很多时候,我们最终会在以后回到我们的模块以添加新功能或进行优化。那时,通过简单地阅读注释比遍历多个断点更容易理解代码。此外,我宁愿花时间思考新的逻辑,也不愿破译现有的逻辑。


1

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

这并不意味着该代码不应被注释。这意味着注释应提供代码按原样编写的原因。


1

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

例如,我通常向每个类成员添加一个注释(为此,我使用文档注释)。这描述了该成员应该执行的操作,但没有描述其操作方式。我发现当我阅读代码,尤其是旧代码时,这可以帮助我快速记住该成员的用途,而且我发现它比阅读代码和解决问题要容易得多,尤其是当代码流跳了很多时。

这只是我的看法。我知道很多人根本不加评论地工作,并说他们认为这没问题。但是,我已经问了一个关于他们六个月前写的方法的人,他们不得不思考几分钟才能确切地告诉我它做了什么。如果对方法进行注释,这不是问题。

最后,您必须记住,注释与代码一样是系统的一部分。在重构和更改功能时,还必须更新注释。这是一个根本不使用注释的论点,因为如果注释不正确,它们会比没有用的情况更糟。

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.