第一个问题
几乎所有人类,在接触到一个需要遵循的新行为准则的时候,都会问一个问题:“为什么我们要遵守这个?”或者是其某种更具排斥性的变体:“这东西到底有什么用?不遵守这个又会怎么样?”
“为什么过马路要走人行横道?”
“为什么开车不能闯红灯?”
“为什么医生要勤洗手消毒?”
“为什么生熟菜板和刀具要分开使用?”
……
从心理学上讲,任何新的制度限制,哪怕只是一点点小的操作方式改动,都会在初期给你带来很强大的排异心态(本宝宝就是不想把玩具收回箱子里……)。其原因是新的规范将你拖离了自己熟悉的舒适区,带来了强烈的不安全感。
简单说就是不习惯,不舒服。(嗯,真正的公主,哪怕压在这二十层床垫子和二十床鸭绒被下面的一粒豌豆,她都能感觉出来。)
而在产品研发中,看起来更有水准的质问会来自于有经验的工程师:
“创意源于自由,这东西会限制更灵活的程序实现”
“我这样做虽然不符合规范,但绝对的高效和没问题”
“我的经验足以避免和处理这些问题,没必要设立什么规范”
……
好吧,你是否已经听出了你身边诸位大神们如下的潜意识?
“你们这些愚蠢的人类才需要遵守规范”
“编码规范是新人的脚手架,对我这样会飞的人没什么用”
“我已经这么忙了还搞这些鸡毛蒜皮的【马赛克】浪费时间。你【马赛克】是仇家派来折腾我的么?”
……
有一篇来自于谷歌前计算机科学家 Mark Chu-Carroll的短文能够很好的回应这些murmur。有兴趣可以点击去接受一次喷洗。
Stuff Everyone Should Do (part 2): Coding Standards(中文译文在这里)。
好的,把头发吹干,看看使用编码规范的最简单的理据。
编码规范的简单经济原理
最简单的理据,往往来自于最朴素的经济追求:这里有利润。
分析编码规范的成本很直接。编写推广学习、部署改进工具,代码走查关注是否违例,所有这些花费在编码规范上的时间的综合,就是编码规范的成本。
而从编码规范中获得的收益相对间接和持久,是通过对你投入软件活动中的时间的精简,通过软件活动中的一系列沟通活动和质量成果逐渐展现出来。
很确定的是,坚持编码规范所带来的收益能够远远高于它的成本。它为你节约的时间,能远远大于你花在它上面的时间。
这绝对是一笔好生意。
能提高代码可读性。
遵守相同编码规范的代码,常常看起来就像是一个人写出来的一样。具有相同的风格是降低学习曲线的有效方式。当你新到一个具有编码规范的公司,读懂某几个函数或模块的写作方式后,常常代表你可以快速读懂相同规范的所有代码了。
能减少人与人之间的沟通成本
理解并遵守相同编码规范的人,就像在讲同一种语言,沟通会快速而准确。而在发生编码风格冲突的时候(不用怀疑,程序员之间的风格冲突是永恒的……),编码规范将会作为仲裁的最终依据,减少沟通的无效消耗。
能提高代码质量
合理的编码规范几乎每一条都会针对一个在编程世界里常见的技术问题。在实践中应用编码规范,就像是常备了一位高水准的代码审查者,能帮助你规避很大比例的常见问题。
简单的来说,在一句If语句中错误的使用了赋值(=)而不是判等(==),可能会带来一个隐藏超过一年的bug,在特定的客户机房,花费你超过一个月的调试时间才能解决。释放一块内存后指针没有清零,可能会带来内存的第二次释放导致系统崩溃。变量没有初始化,可能会在函数栈的多次值传递后,将程序引入一个未知的随机态……
这许许多多的常见错误,都可以通过在头脑中的强烈规范意识,以及严格的代码规范审查所避免。(我不太喜欢用“低级错误“这个词,因为实际上几乎所有的程序错误都是”低级错误“。)
能为团队工作建立脚手架
团队,需要规范。
在所有的团队中,不是每一个成员,都拥有相同的知识领域、教育程度、行业背景、项目经验,从而不是每一个成员,有着相同的思维深度、隐喻哲学和学习能力。
建立合理的规范,可以建立团队在技术上沟通的模式,前文已提及,更重要的是,还可从团队内部,重(chóng)用已有的程序智慧,为成员提供了有高度的脚手架,避免成员个体在程序设计上特定弱点所带来的质量短板。
团队中个人的优势能力决定了团队的质量能力的上限,而编码规范的执行,则决定了团队代码质量的下限。
能节约智力投入
还记得在你在遥远的中学时期吗?英文考试的倒数第二题永远是找茬题:给十多行英文让你找错。
很快你就自己总结了一个检查表,包括在试卷上出现过的所有错误类型(单复数错误、时态错误、介词错误……),此后考试时对每一行都遍历一遍检查表,基本上快准狠。自然而然的找你妹的题就变成了完全不花智商的按图索骥送分题。
编码规范就是这样的一个检查表,它必然是程序世界和公司经验的知识沉淀物,它能帮助你减少思考的密集程度,将最重要的智力资源投入到真正需要你去设计和关注的核心点上。
你不用再在多种程序风格中进行翻译和映射,因为只有一种程序风格。你看一眼函数名就知道它是做什么用的来自于什么模块,你看一眼变量名就知道它是什么内容大概应该是什么类型。
你不用再去思考变量的初值,因为变量的初值总在定义的时候有说明,对整数来说大多是0,对指针来说大多是NULL。
你不用再去思考来自于外部的一个buffer是否需要你去释放,或者你定义的buffer应该在什么地方去释放。
……
是的,我们希望在一切在程序世界里可能有争议的地方,或者完全没有争议的地方,都有我们自己的规定和习俗。
让软件工程师在最常见的程序过程中沿袭习俗,在关键和艰难的创新点上灵活创新,继而充分的用80%以上的智力来解决20%的核心问题。这才是对软件工程师团队的最大效率提升。(请把你积攒的每一点怒气都用在释放大招上!)
巴比伦之塔
110V和220V的电压哪一个更科学合理? 不同的人有不同的理据,不同的国家有着不同的标准。没有谁能说服谁。
同样,缩进是4个空格还是2个空格?函数体左边花括号应该在行尾还是在行首?注释应该用“/**/”还是用“//”?
这些问题软件行业中有着永恒的争论。这些争论是宗教狂热信仰式的,也许直到人类灭绝或太阳熄灭也不会有结论。
可能采用这些争论中的任何一个答案都是okay的,或从成本收益的角度判断,其区别微乎其微。为了建设团队内部沟通的巴比伦之塔,为了代码的可读性,公司、项目、模块,其内部一定要有统一的答案。
略带讽刺意味的是,常作为全人类之间无障碍沟通标志的巴比伦之塔,居然也有巴别塔,巴贝塔、巴比伦塔、通天塔等多个中文名。但对于一条具体的编码规范,我们不能留下任何争论,只能有确定的结论。即,我们需要选择一个答案执行。
在执行过程中,如果你对已经制定的编码规范还有任何疑惑,唯一的处理方式是:给出足够强的理由,说服所有人,修改或者抛弃。当你找到的理据不够强大还无法说服大家时,请把那个撅着嘴的小孩放在心里,严格遵守团队现有的规范。
它一定能帮到你。