当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《什么是自我记录代码,是否可以替换记录良好的代码?》经验,为你挑选了17个好方法。

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

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

帮助我理解的观点.

什么是自我记录代码

它真的可以取代评论和记录良好的代码

是否存在比记录良好和注释的代码更好的情况

是否存在代码无法在没有注释的情况下进行自我记录的示例

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

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

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

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



1> ine..:

好吧,因为这是关于注释和代码,让我们看看一些实际的代码.比较这个典型代码:

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.

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

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


虽然整个块应该是一个具有描述性名称的函数;)
我想念的一个评论是:为什么5秒?
引力的单位是多少?您可以添加到变量名称的数量有限制.在某些时候,你必须解释*你想要做什么*.这通常是*不明显*,这就是你需要评论代码的原因.说代码是自我记录是绝对的垃圾,它只是自我*描述性*.
是的,函数displacementDueToGravity(int timeInSeconds,float gravitationalAcceleration = 9.81)对我来说更容易阅读.
对描述性函数名称的另一次投票.它没有给出等式本身,但我不认为这是必要的.
@Nick:单位!请在所有变量名称上单位!timeoutSec或timeoutMs准确地描述了变量,而当1000个线程等待2000秒(而不是ms)超时时,超时将成为寻呼机调用.
这个真的需要放在一个带有描述性名称的函数中.那时它变成了真正的自我记录!实际上,每当您发现自己编写注释来解释代码块时,这是一个明确的信号,表明您需要将该代码块提取到具有通知名称的方法中.即使您只调用过一次该方法.
在某些语言中,(1/2)将使用值作为整数,并且由于截断错误而最终为0.您可以通过执行(1.0/2.0)或仅使用0.5来避免这种情况

2> OregonGhost..:

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

为每个类,成员,类型和方法AND编写文档注释(Doxygen,JavaDoc,XML注释等)

清楚地评论代码中任何自我记录的部分

为解释意图的每个代码块写一个注释,或者代码在更高的抽象级别上执行的操作(即查找大于10 MB所有文件而不是遍历目录中的所有文件,测试文件大小是否大于10 MB,如果为真,则收益率返回)

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


点nr.3应该是点nr的一部分.1恕我直言,如果一个方法如此复杂以至于需要对几个代码块进行高抽象注释,那么每个这样的代码块应该是一种新方法.
+1表示"并不意味着应该没有评论",这似乎是某些人的意见.
对我来说一个好的经验法则是评论不应该解释代码正在做什么,但可以用来解释它为什么这样做.换句话说,注释一个代码块来解释它为什么存在,而不是它是如何工作的.如果你可以将块分解为它自己明确命名的方法,那就更好了.这就是自我记录代码的全部意义所在.
仍然没有*需要*评论:public static Collection filesGreaterThan(File path,int sizeInBytes);

3> andygeers..:

代码本身始终是对代码所做内容的最新解释,但在我看来,它很难解释意图,这是评论最重要的方面.如果它的正确写入,我们已经知道什么代码的功能,我们只需要知道为什么地球上它吧!


我认为那些可以回答高级别的原因,但他们没有解释这样的事情:"我正在将这个结构填充这么多字节,以便在传输到某个不起眼的平台时保持正确对齐." 对于那些,代码注释是保存机构知识的最佳方式.
@tsellon,您的自动化规范可以告诉您,以及检查实现代码的代码.因此,如果实现以某种方式更改,则规范会中断.这有多好?当实施代码不再执行注释时,提醒您的注释?

4> Loofer..:

有人说过

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


在编写代码时你理解的东西实际上很难让其他人稍后理解,即使其他人实际上是你自己在几个月/几年内.
我经常发现周五早上写的东西很难在周一早上写下来:)

5> Scott Dorman..:

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

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



6> Mike Burton..:

我认为问一个特定的代码行是否是自我记录是相关的,但最后如果你不理解一段代码的结构和功能,那么大多数时候评论都没有帮助.以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);

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


你需要更多的upvotes,你的例子解释了为什么我们应该使用函数名来记录意图.

7> EBGreen..:

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

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


垃圾.代码中的好评绝对有自己的位置.以两个同样正确的方法之间进行选择来解决问题为例.解释为什么选择一种方法而不是另一种方法的注释是非常有意义的,你永远无法从代码本身获得.
我不认为人们会以与我相同的方式引用它.我认为你应该努力总是编写一个非常清晰的代码,不需要进行评论,但是你必须接受它是一种在现实中永远不会起作用的理想.
如果有两种EQUALLY CORRECT方法,那么为什么选择一种方法而不是另一种方法呢?

8> Wedge..:

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

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

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

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

等等.

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

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


一个例外:糟糕的程序员.我看过评论说代码正在做一些事情,但事实并非如此.然后我问自己:我应该修复代码还是注释?

9> Gulzar Nazim..:

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

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

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



10> Steven Huwig..:

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

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

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)

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

我在撰写"自我记录代码"时看到的最好的论点是,它避免了自由文本评论的问题,因为它不符合编写的代码.最好的批评是,虽然代码可以自己描述它在做什么以及如何做,但它无法解释为什么某些事情以某种方式完成.



11> Avdi..:

为了:

自我记录代码是向读者明确表达其意图的代码.

不是完全.评论总是有助于评论选择特定策略的原因.但是,解释代码部分正在做什么的注释表明代码不够自我记录并且可能使用一些重构.

评论谎言并且过时了.代码总是告诉更有可能说实话.

我从来没有见过,其中的情况下什么的代码不能进行足够清晰无意见; 然而,就像我之前所说的那样,有时必须/有帮助包括对原因的评论.

然而,重要的是要注意,真正的自我记录代码需要大量的自我和团队纪律.你必须学会​​更具声明性地编程,并且你必须非常谦虚并且避免使用"聪明"的代码来支持代码,这些代码很明显,似乎任何人都可以编写代码.



12> ddimitrov..:

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

/**
 * 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> ulm..:

当您阅读"自我记录代码"时,您会看到它正在做什么,但您无法总是猜测它为什么以这种特定方式进行.

有许多非编程约束,如业务逻辑,安全性,用户需求等.

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

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



14> Onorio Caten..:

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



15> catfood..:

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



16> Stefano Bori..:

区别在于"什么"和"如何".

你应该记录例程的"内容".

除非特殊情况(例如,参考特定的算法论文),否则您不应记录它是如何做到的.这应该是自我记录的.



17> JoeOD..:

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

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

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有