我的代码需要注释

在众多类型的软件项目中,有一种 “脏活累活”,

那就是,把老系统下线,用新系统替代它。


这项工作,我们常称之为 “功能迁移”。

用另外一套代码,实现既有系统的所有功能。


这看似不是很难,

毕竟旧系统提供了哪些功能,不都在代码中吗?抄过来就行了。

其实不然。


因为大部分系统都没有一个详细的规格说明,

用户也可能正以各种 “意想不到” 的方式依赖着它,

还原系统的所有外部效用,需要兼容很多这样的场景,非常容易出错。


在进行 “功能迁移” 的时候,我们最害怕遇到的是那些缺少注释的代码,

不明白代码的原作者当初为什么要这样写

所以,“功能迁移” 简直是程序员的噩梦。


是什么原因导致代码中的注释这么少呢?

我想很大一种可能是,人们理解错了 “代码即文档” 的本意


所谓 “代码即文档”指的是,优秀的代码不需要注释,它自己就能解释清楚。

这是对别人的一种赞誉。

可是,如果这样夸赞自己的话,就有点自命不凡了。


你为什么不洗脸?因为脸型好,不洗也帅。

正视自己的水平

Apache 基金会副总裁 Niclas Hedhman 在 2016 中国开源年会上,

曾做做过一次演讲,主题是 《屋中的大象》。

其中提到了优秀程序员的占比问题。


60% 的程序员,认为自己是天才的或良好的程序员,

只有 30% 左右的人,认为自己是一般的程序员。

可实际上,天才程序员只有不到 1%,大量的程序员属于一般、较差的程序员。


所以在写代码的时候,我们应该先正视自己的水平

我们没有那么优秀,“我太愚蠢了,写不出好代码”。


理解了这件事情之后,就能明白,

很多上下文中提到的 “优秀程序员” 并不是在说我们。


假如有人说,“优秀的程序员应当尽量不写注释”,就不是在说我们

“优秀程序员” 不写注释,是因为他们的代码写的太好了,没必要多此一举,

而我们则不然,代码写的本来就不好,再不写注释会更加的晦涩难懂

当心矫枉过正

其实很多建议,是针对某些有倾向性的人群来说的,

而且这些建议也未必凑效


例如,孟子在 《尽心章句下》中写道,

尽信书,则不如无书。


这句话是针对于 “尽信书者” 而言的,

如果本来就有怀疑精神了,再因为这句话变得 “事事怀疑”,那就矫枉过正了。

也就是说,只要能避免 “尽信书”,就已经达到劝诫的目的了。


类似的,在 《高效能程序员的修炼》 中,作者说,

避免写注释,你应该总是专注于编写代码,而忘了还有注释这种东西的存在。


这是一种建议,通过这样的练习,有可能会让我们的代码写的更清晰,也有可能练不成。

这句话是针对于那些过于依赖注释这根 “拐杖” 的人说的,

如果因此坚决不写注释,那也是矫枉过正了。

信息丢失

由于计算机只需要 “功能该如何执行” 这部分信息,

所以,代码中包含的信息其实是不全的,有很大一部分信息并没有保存到代码中。


这样的代码在维护起来,就会遇到麻烦。

以下列举了两种常见的信息丢失场景:编码动机的丢失,功能用法的遗漏

(1)动机

Martin Fowler 说,

Any fool can write code that a computer can understand.

Good programmers write code that humans can understand.


机器只要知道怎样执行就行了,人还要知道代码为什么要这样写

所以,对于 “为什么” 这样的动机信息,代码很难表述清楚。

这就像下棋一样,棋谱无法写明双方的用意。


所以,代码和文档是不可分的,

它们将程序开发时的环境信息,尽可能多的保存了下来。


“功能迁移” 为什么困难,是因为开发时的环境信息已经丢失了,

当时所有人都都认为是再正常不过的事情,现在已无从得知了。


比如,我在进行迁移时,发现代码中有一份白名单,白名单内硬编码了几个名字。

代码写的不能算不清晰,一看就知道这是一个白名单,命名也很规范,

但是为什么需要这个名单呢?名单中为什么只有这些名字呢?


可能只有当时写代码的人知道吧。

(2)用法

不知道你有没有遇到过这样的场景,当我们咨询他人某个功能怎么用的时候,

居然让我们去读源码,来推断出功能的使用方式。


这其实是一种很不好的编码风格,“功能该如何被使用” 其实是非常重要的信息,

会使很多缺陷都出在系统的边界上,大大增加集成开发的难度和成本。


一个完整的功能,应至少包括两个部分:

(1)使用说明

(2)具体实现


使用说明无法写到代码中,因为执行代码的机器不管这些。

它只管按照代码描述的方式运行即可。

所以,这一部分的信息的遗漏,就得通过注释或者文档的方式来写下来。

结语

对于注释而言,我觉得应该正反兼顾,不宜偏激,

(1)代码能交代清楚的,写到注释中就是画蛇添足

(2)代码不能交代清楚的,仍坚持不记下来的就是矫枉过正


任何时候,当别人问 “为什么不写注释” 的时候,

回答 “代码即文档” 都应感到羞愧,我们不该把赞扬别人的托词用在自己身上。


反之,我们应该把头低下来,耐心倾听别人的建议,

这样才能把代码写的越来越好,

从糟糕的程序员,变成一般的程序员吧。