写代码是什么,不同的人有不同的答案,但有一个答案我很喜欢:
Writing code is sharing the experience of understanding the requirements/implementation.
编写代码就是分享理解需求/实现的经验。
编码始于需求,我们写下的代码,是对需求的实现和描述,体现了我们对需求的理解。
而当别人阅读代码的时候,我们希望对方能通过代码理解当时的需求,理解我们的设计,这就要求代码具有很高的可读性。
提高可读性,除了代码本身,注释也发挥着很大的作用。
虽然逐行记录代码的功能通常没有太大用处,因为通过阅读代码就能理解其含义,
但编写可读代码的一个关键目标是降低读者在阅读代码时需要记住的努力和细节数量。
因此,对我来说,注释可以是降低读者认知负担的工具。
以下代码片段就是一个好例子:
/* Initial Stack: array */ lua_getglobal(lua,"table"); lua_pushstring(lua,"sort"); lua_gettable(lua,-2); /* Stack: array, table, table.sort */ lua_pushvalue(lua,-3); /* Stack: array, table, table.sort, array */ if (lua_pcall(lua,1,0,0)) { /* Stack: array, table, error */ /* We are not interested in the error, we assume that the problem is * that there are 'false' elements inside the array, so we try * again with a slower function but able to handle this case, that * is: table.sort(table, __redis__compare_helper) */ lua_pop(lua,1); /* Stack: array, table */ lua_pushstring(lua,"sort"); /* Stack: array, table, sort */ lua_gettable(lua,-2); /* Stack: array, table, table.sort */ lua_pushvalue(lua,-3); /* Stack: array, table, table.sort, array */ lua_getglobal(lua,"__redis__compare_helper"); /* Stack: array, table, table.sort, array, __redis__compare_helper */ lua_call(lua,2,0); }
或许你会认为,只要我把代码写得足够清晰,代码本身就是自解释的,我不需要注释。
但我觉得下面这段话说得很对,大多时候这都是 “自欺欺人”:
许多开发者抱有一种不切实际的信念,认为如果代码足够清晰,就不需要使用注释。
这是一个美好的前提,但根本不成立。
第一个问题是,大多数开发者面临巨大的时间压力,没有时间将代码写得如此清晰,以至于不需要进一步的注释。
事实上,程序员更常见的经历是,看到自己六个月前写的代码时,会想 “我真不敢相信这是我写的!”
不要自欺欺人,以为你可以写出如此清晰的代码,以至于不需要注释就能理解。
另一个问题是, 代码仅解释了事情是如何完成的,而不是为什么以那种方式完成, 特别是当有明显的替代方案时;1
如果 “为什么” 不是显而易见的,技术债务就会在缺乏解释的情况下累积。
请注意,如果没有这样的解释性注释,代码可能会变得极其难以维护, 因为没有人敢去触碰它,这正是技术债务的定义 。
写代码和写作有点相似,代码是写给人看的(包括自己),要尽可能地清晰传达代码的意图,而注释可以帮助我们揭示代码中隐含的意图,让读者更好理解。
理解代码,最终还是依靠“读者”自己,或许我们写的注释还不足以将一切描述清楚,但至少通过注释,我们补充一些信息,辅助别人阅读我们的代码。
这里的关键是你我都陷入了同一个陷阱。
我在 18 年前重构了那个旧算法,我认为所有那些方法和变量名称会使我的意图清晰——因为我理解那个算法。
你在一段时间前写了那段代码,并用你认为能解释你意图的注释进行了装饰——因为你理解那个算法。
但我的变量名在 18 年后并没有帮助我。它们也没有帮助你,或者你的学生。而你的注释也没有帮助我。
我们在箱子里试图与那些站在外面、看不到我们所看到的东西的人沟通。
说到底,向一个对你试图解释的细节不熟悉的人解释某件事是非常困难的。
我们的解释往往只有在读者自己理清了细节之后才有意义。