代码维护:要在代码中添加注释还是仅将其留给版本控制?


42

我们被要求在我们对代码进行的每个更改中添加带有开始标签,结束标签,描述,解决方案等的注释,作为修复错误/实现CR的一部分。

我担心的是,这会带来任何附加值吗?实际上,我们具有版本控制历史记录中的所有详细信息,这将有助于我们跟踪每个更改?

但是我的领导者坚持将注释作为一种“好的”编程习惯。他们的论据之一是,当必须对CR进行范围界定/更改时,如果没有评论,那将很麻烦。

考虑到这些更改将主要在代码之间进行,是否真的有助于为我们所做的每一个更改添加注释?我们不应该把它留给版本控制吗?

Answers:


43

你是绝对正确的。跟踪更改是版本控制系统的工作。每次执行提交时,都应该编写一条提交消息,说明已完成的操作,如果这是一个错误修复程序,则应参考您的错误跟踪系统。在代码中添加注释

// begin fix for bug XXXXX on 10/9/2012
...
// end fix for bug XXXXX

每次您修复错误时,都会迅速使您的代码变得不可读且无法维护。这也将导致在两个地方复制相同的信息,这将使情况更糟。

注释不应用于错误跟踪,也不应描述您的代码在做什么。他们应该解释为什么您要执行X或为什么要以这种特定方式进行X。如果您需要编写注释来解释代码块的功能,那是一种代码味道,表明您应该将此代码块重构为具有描述性名称的函数。

所以代替

// fixed bug XXXXX on 10/9/2012

您可能有一条评论说

// doing X, because otherwise Y will break.

要么

// doing X, because doing Y is 10 times slower.

12
+1表示解释“什么”的注释的代码味道。很高兴看到这样的响应:代码注释不是自动的好处,因为注释更多>注释更少。我什至可能会撤回一个级别,并认为在某些情况下,甚至描述“为什么”的注释也可能会散发出气味,表明代码不清楚。例如,如果我可以注入BubbleSorter或QuickSorter,则注释“我正在使用QuickSorter,因为它速度更快”与“注入快速分类器”相同。YMMV。
Erik Dietrich

53

使用最好的工具完成工作。 您的版本控制系统应该是记录错误修正和CR的最佳工具:它会自动记录日期和更改者;它永远不会忘记添加一条消息(如果您已将其配置为要求提交消息);它永远不会注释错误的代码行,也不会意外删除注释。而且,如果您的版本控制系统已经比注释做得更好,那么通过添加注释来重复工作是很愚蠢的。

源代码的可读性至关重要。注释不清的代码库会给出所有错误修正和CR的完整历史记录,因此根本无法阅读。

但是不要完全跳过注释: 好的注释(不要草率地记录每个错误修正和CR的每个开始/停止/描述/解决方案)可以提高代码的可读性。例如,对于添加的一些棘手的或不清楚的代码来修复错误,最好在表单中添加注释以// fix ISSUE#413告诉人们在问题跟踪器中可以找到更多信息。


29
我同意,除了一件事:fix ISSUE#413在代码中不是一个好的注释。您应该能够理解代码,而不必参考外部文档。与其给出一个随机数,不如实际解释为什么为什么要执行此操作才需要这段棘手的代码。这就是注释的含义:解释不明显的代码部分。

12
@poke-感谢您指出这一点。我想我应该补充一点,我使用表格注释的唯一地方fix ISSUE#413是问题如此复杂(一个极端的OS和配置相关的极端情况,或者仅由特定的不良客户数据触发),以至于对其进行充分描述几段;此类问题最好由问题跟踪程序IMO处理。即使这样,简短的描述还是不错的。
2012年

8
@poke:我想说的开头 fix ISSUE#413是非常好的,甚至更可取,只要它还提供了有关#413是什么问题的合理数量的信息。仅仅总结问题报告而没有提供指向它的指针,对于需要所有细节的未来读者来说,生活变得更加困难。
基思·汤普森

我同意戳-您永远不必参考外部资源来理解代码。如果我正在查看更改,则会中断流程。我必须去问题跟踪器,提出问题,并阅读所有内容。如果您更改问题跟踪器,会发生什么?fix ISSUE#413评论的完整性可能会很好,但不要将其用作拐杖。
迈克尔·迪恩

“它永远不会忘记添加一条消息(如果已将其配置为要求提交消息);它永远不会注释错误的代码行或意外删除注释。” 我们只是处理了SVN自身损坏,并且不得不从备份中还原的问题。我们能够找到尚未备份的代码,但是当我们重新提交更改时,几个单独的提交成为一个。我的观点永远不过分,不要忘了人们一定要迁移到新的VCS软件,并且带来修订历史可能不可行。
安迪

7

代码中的注释是对代码什么在那一刻。在任何给定时间拍摄快照都不应引用该代码的旧版本(或更糟糕的是,将来的版本)。

VCS中的注释是关于代码如何更改的。他们应将其视为有关发展的故事。

现在,每个更改都应包含注释?在大多数情况下,是的。我想象的唯一例外是,预期的行为已经记录在案,但由于错误而不是您所得到的。对其进行修复可以使现有注释更加精确,因此不必进行更改。该错误本身应记录在故障单历史记录和提交注释中,但如果代码看起来很奇怪,则仅应记录在代码中。在这种情况下,a // make sure <bad thing> doesn't happen应该足够。


8
我会对此表示赞同,但我真的不同意“在大多数情况下,所有更改都应包含评论?”。入住/提交评论,是的,绝对可以。代码注释,绝对不是必须的。
CVn 2012年

6

我真正欣赏的一种评论是:

//这是针对提案2的业务规则5实施的

或您用来收集需求的任何技巧。

这有两个优点,一个是让您无需搜索即可找到实现给定算法的原因,另一个是可以帮助您与处理/创建需求文档的非软件工程师进行交流。

对于较小的团队,这可能无济于事,但是如果您有满足需求的分析工具,那将是无价之宝。


2
但是这是不同的,因为它提供了与版本控制正交的可追溯性:代码与其实现的需求规范之间的连接。
卡兹(Kaz)2012年

在将版本控制与错误/要求结合在一起的系统中,无需注释即可提供完整的可追溯性。有时以其他方式工作会有所帮助。给定来自SCM的文件,请告诉我什么时候实施了哪些要求。或者,如果有要求,请告诉我为实现该功能而修改的所有文件。
iivel 2012年

4

当您的领导者说注释是一种不错的编程习惯时,您的领导是正确的,但是也有例外。为您所做的每一项更改添加评论就是其中之一。您说对了,这应该属于版本控制系统,这是对的。如果您必须将这些注释放在一个地方,那么VCS是您的最佳选择。源代码中的注释往往会变得陈旧且无法维护。没有评论比不好的评论要好得多。您不希望在两个地方(在代码和VCS中)都存在不同步的注释。目的是通过使代码更改具有唯一的真实来源来保持事物的干燥。


3

除了其他人所说的,还要考虑如果更改对整个系统产生连锁反应会发生什么。假设您在实施变更请求的过程中重构了核心接口的一部分-这种变更可以轻松地触及任何非平凡软件中很大一部分的源代码文件,而这相当于平凡的变更(类或方法名称更改)。您是否应该通过这种操作触及的每个文件来用此类注释手动注释文件,而不是依靠VCS自动完成所有操作?在一种情况下,您正在使用任何体面的重构工具完成五分钟的工作,然后进行重新编译以确保没有破坏构建,而另一种则可以轻松地花费一天的时间。有什么特别的好处?

还要考虑移动部分代码时会发生什么。我与之合作的数据库开发人员中的一员主要是在“每一行SQL都应注以更改版本的注释,并且我们将为每个文件做单独的修订历史记录,因为这样一来,它很容易看到谁在何时何地改变了什么”。当更改按更改单行的顺序。就像我最近为解决一个严重的性能问题所做的那样,当您拆分一个较大的查询的一部分以引入临时表,然后更改某些查询的顺序以更好地适应新的代码流时,它的工作效果并不理想。当然,与前一个版本的差异几乎没有意义,因为它说文件的三分之二已更改,但检入注释也类似于“针对性能问题的重大重组”。到您手动查看两个版本时,很明显,大部分零件确实是相同的,只是四处移动。(而且,相关存储过程的执行时间从通常的半分钟以上延长到了几秒钟。到那时,

除了极少数例外,VCS IMNSHO负责更改跟踪和问题引用。


3

我通常遵循以下规则:如果更改是显而易见的,并且生成的代码没有引发问题,没有实质性地还原或实​​质上更改任何先前的行为-然后将其留给VCS来跟踪错误号和其他更改信息。

但是,如果存在不明显的更改,则更改了逻辑-尤其是以非显而易见的方式显着更改了其他人所做的逻辑-添加类似“此更改是为了做到这一点,并且由于错误#42742”。这样,当有人查看代码并想知道“为什么在这里?这看起来很奇怪”时,他就可以从中获得一些指导,而不必通过VCS进行调查。这还可以防止由于人们熟悉其他代码的旧状态而又不注意到自那以后已被更改而导致他人中断其他更改的情况。


2

与版本控制相关的注释不属于源文件。它们只会增加混乱。由于可能需要将它们放在相同的位置(例如文件顶部的注释块),因此当合并并行分支时,它们将导致仅注释讨厌的冲突。

可以从版本控制中拉出的任何跟踪信息都不应在代码主体中重复。这适用于诸如RCS结帐关键字之类的愚蠢想法,以及类似的想法$Log$

如果代码曾经超出版本控制系统的范围,那么有关其历史的注释便失去了上下文,因此失去了其大部分价值。为了正确理解更改的描述,我们需要访问修订版本,因此我们可以查看与先前版本的差异。

Linux内核中的某些旧文件具有很大的历史注释块。这些可以追溯到没有版本控制系统时,只有压缩包和补丁程序。


2

代码中的注释应尽量少且准确。添加缺陷/变更信息没有价值。您应该使用版本控制。一段时间以来,版本控制提供了一种更好的更改方式-我们使用ClearCase UCM;UCM活动是根据缺陷编号,更改区域等(例如,defect29844_change_sql_to_handle_null)创建的。

签到评论中首选详细评论。

我倾向于提供有关背景信息的详细信息,由于某些副作用而未实施的解决方案的详细信息。

Pramagic程序员和CleanCode导致以下准则

将低级知识保留在其所属的代码中,并保留注释以供其他高级解释使用。

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.