我有一个同事,他坚持认为他的代码不需要注释,这是“自文档”。
我已经审阅了他的代码,虽然它比我看到的其他人编写的代码更清晰,但我仍然不同意自文档化代码与经过注释和文档化的代码一样完整和有用。
帮我理解一下他的观点。
什么是自文档代码
它真的能取代注释良好和文档化的代码吗
在某些情况下,它是否比有良好文档和注释的代码更好
是否存在代码不可能在没有注释的情况下自文档化的例子
也许这只是我自身的局限性,但我看不出这怎么能成为一种好的练习。
这并不是一个争论——请不要提出为什么注释良好并有文档记录的代码是高优先级的原因——有很多资源都表明了这一点,但它们对我的同行来说并没有说服力。我认为我需要更全面地了解他的观点,才能说服他。如果你有必要,可以提出一个新的问题,但不要在这里争论。
另外,那些反对自我记录代码的人——这主要是为了帮助我理解自我记录代码传播者的观点(即积极的方面)。
我认为,质疑某一行代码是否具有自文档性是有意义的,但最终,如果你不理解一段代码的结构和功能,那么大多数时候注释是没有用的。以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);
根据我个人的经验,很少有绝对需要注释的“正常”编码情况。举个例子,你有多频繁地使用自己的算法?基本上,其他一切都是构建系统的问题,以便编码器能够理解正在使用的结构以及驱动系统使用这些特定结构的选择。
对于许多有效的答案,我想再提供一个观点:
什么是源代码?什么是编程语言?
机器不需要源代码。他们很高兴运行组装。编程语言是为了我们的利益。我们不想写汇编。我们需要理解我们在写什么。编程就是写代码。
你能读懂你写的东西吗?
源代码不是用人类语言编写的。它已经被尝试过(例如FORTRAN),但并不完全成功。
源代码不能有歧义。这就是为什么我们必须在其中加入比文本更多的结构。文本只适用于上下文,当我们使用文本时,我们认为这是理所当然的。源代码中的上下文总是存在的。想想c#中的“使用”。
大多数编程语言都有冗余,这样编译器就能在我们不连贯的时候发现我们。其他语言使用更多的推理,并试图消除冗余。
类型名、方法名和变量名在计算机中是不需要的。它们是供我们参考的。编译器不理解语义,这是我们要用的。
编程语言是人与机器之间的语言桥梁。它必须对我们来说是可写的,对他们来说是可读的。次要要求是它应该对我们来说是可读的。如果我们擅长语义,并且擅长构建代码,那么即使对我们来说,源代码也应该很容易阅读。最好的代码不需要注释。
但是复杂性潜伏在每个项目中,您总是需要决定将复杂性放在哪里,以及吞下哪只骆驼。这些是使用注释的地方。
自文档代码是一个很容易解决的问题,随着时间的推移,代码、注释和文档会出现分歧。编写清晰的代码也是一个约束因素(如果你对自己有那么严格的话)。
对我来说,以下是我努力遵循的规则:
Code should be as easy and clear to
read as possible.
Comments should give reasons for
design decisions I took, like: why
do I use this algorithm, or
limitations the code has, like: does
not work when ... (this should be
handled in a contract/assertion in
the code) (usually within the function/procedure).
Documentation should list usage
(calling converntions), side
effects, possible return values. It
can be extracted from code using
tools like jDoc or xmlDoc. It
therefore usually is outside the
function/procedure, but close to the
code it describes.
这意味着所有三种记录代码的方法都很接近,因此更有可能在代码更改时被更改,但它们所表达的内容并不重叠。