据说,赵国的首都邯郸的人走路的姿态很好看,动作非常优雅、轻快。 燕国有一个少年听到这个传说,非常羡慕邯郸人,就走了很远的路去赵国,想学习邯郸人走路的方法。刚开始,他整天站在街头,仔细研究每个人走路的姿态,再慢慢模仿他们,可是都没有成功。后来,他想可能是受到过去走路习惯的影响,所以,他决定要忘掉以前走路的方法。从那时候起,他更专心研究邯郸人走路的姿势,不过,再怎么努力他还是学不会,最后他只好放弃。可是,因为他把以前走路的方法忘得一干二净,已经不知道该怎么走路,只好一路爬着回去。 http://www.hydcd.com/cy/gushi/0236hd.htm
不知不觉间,代码也写了二十余载,我已成精了。借着过来人的身份和语气,有一件事情我一直都特别喜欢吐槽:无论过去多少年,中国的嵌入式软件开发者群体似乎一直对一个叫做“编码规范”的东西趋之若鹜,仿佛是什么了不得的武林秘籍,学会了就可以叱咤武林让让人不敢小觑;又亦或是什么内功心法,需要每日研读或与它人细细品读交流,以求它日可以参透其中奥秘,从此内力大增,用心跳就可以虐死对手。
君不见,曾几何时《某为编程规范》在网上被广泛传抄,互联网时代虽然无法“洛阳纸贵”,却曾经引得某公司的公关部门到处发函让站长们删帖;时过境迁,虽然某为的编程规范也不至于热度全无,但对冠名于国外大厂大公司的编码规范的追捧却已悄然成为当下的热门——仿佛如果说不出自己使用的规范来自哪个大门派,都不好意思跟人家打招呼。
可拉倒吧!
在兄弟们浪费太多时间之前,可曾了解过自己苦苦追寻和模仿的究竟是个什么东西?
【编码规范的本质是什么?】
要理解编码规范的本质,其实并不复杂:
这里,你会很容易注意到三个关键字:“一定范围”、“强制推行”和“编码习惯”。抓住这三点,编码规范的本质就像“任意不在同一直线上的三点确定一个平面”一样——没得跑了。
首先来说说这个“编码习惯”,其实很好理解,它就是字面意思——一个人写代码时候的某种习惯,高情商叫风格,低情商叫“我就爱这么干,别问我为啥,我要么不知道,要么等我编个理由告诉你”。总之呢,编码习惯带有强烈的主观性、基本上可以认为缺乏强有力的客观依据,在稳定性和一致性方面其实就是水中花镜中月——不能说完全没有,只能说毫无可信度。
不信么?今天你看了一个大牛的代码,觉得:
“哇!好牛逼”,
“大牛这么做一定有什么深意”
然后不自觉的就学着人家的编码规范来了。过了几天,你可能又碰到了另外的大牛,或者是什么明星开源项目……咋说呢……如果用男女关系来形容兄弟们的行为,那就是妥妥的渣男/渣女——没得洗。
你跟我说说,哪儿来的稳定性和一致性?还不如先问问“你是谁的粉”比较靠谱。
很多时候,一个程序员自己的编码习惯可能一辈子都没有鲤鱼跃龙门——成为编码规范的机会;但如果有朝一日,你满足了以下两个条件,你的编码习惯就是妥妥的编码规范了:
此时,只要你乐意,完全可以在“你控制的范围内”“强制”推行你自己的编码习惯——恭喜你,一个只属于你的编码规范就诞生了。
【编码规范的“原罪”】
搞懂了编码规范诞生的原因,接下来很自然的,就要聊一聊伴随编码规范一起诞生的“原罪”了。
要理解什么是编码规范的原罪,首先必须要讲清楚“编码规范”(或者说“遵守编码规范”)的意义。然而,有些东西你非要向字典一样去从正面解释往往非常抽象,但稍微打个比方,就简单明朗了——实际上:
编码规范的作用几乎完全等效于人类自然语言文字中的书法。
简单说,编码习惯就是关于“你如何写字的”,而编码规范就是“一群人所遵守的书法风格”。这么一比方,也许你立马注意到了:
说的再直白一点:当你在追求“如何写出精修文章时”,追求“书法”,是浅薄的,而且毫无意义的。当你在追求如何写出好的程序时,你需要的是数据结构、算法、操作系统、软件工程、设计模式、开发思维之类的知识,而不是关于如何把代码写的多么漂亮,多么“规范”的书法——或者说表面功夫。认真说起来,连这里“怎样算作代码写的规范”,从一开始就只是某几个人的主观概念罢了。
正如景秀文章往往也是用赏心悦目的书法写出来的;注重表面的编码规范也并非是什么大罪大恶需要我们弃之如粪土。要知道这其中区别,就必须要谈一谈编码规范的原罪。
正如我在之前一篇文章《真刀真枪模块化(1)——一本糊涂账》所提到的那样:
……读懂一段程序,实际上就是要通过死的代码逻辑去反推模块构作者的思维,这是一个逆向过程,这是一个人与人之间用代码进行间接交流的过程,当逻辑本身较为复杂时,显然比将自己的思维直接翻译成程序(重新开发一个)更为困难。 傻孩子,公众号:裸机思维真刀真枪模块化(1)——一本糊涂账
这里,我提到了一个关键的事实——阅读他人代码是非常耗时和困难的。这样的事情无时无刻不在发生:当我们拿到一段代码时,想通过了解它的内容来判断好坏几乎是不可能的——这不光意味着你要花费时间去阅读它,可能你根本不想去阅读,或者根本没有这样的时间去阅读。此时,要想判断一段代码的好坏就只能通过非常表面的东西来进行了——是的,就是看你写的字漂不漂亮。
如果明确知道这是“名人大家”的作品,或是出自某个大厂的作品,事情就变得非常简单:只要学习历来文人是如何在同行面前显示自己学识渊博的方式——花式吹就行了。
如果要评价的对象是同辈的作品,或是某个来源不明的作品,大家就一下开始“审慎起来”,仿佛瞬间化身为严肃的艺术评论家——在严肃而充满理性的批判声中,自己“高超水平”和“恨铁不成钢的惋惜”跃然纸上。
呜呼哀哉,文人相轻,这味儿太冲了。
前面我们说过,编码规范的本质是编码习惯,编码习惯拥有非常强的主观性,因而缺乏客观标准。然而,这话只说了一半,事实上,并不矛盾的一点是,如果某个编码习惯出自于“较为严谨认真”的人之手,这样的编码习惯也便“主观的”拥有了一定的客观性——这完全是由提出的人的特性而决定的——因此依然是主观的。
这可就头疼了。因为这些“严谨认真”的人,他们在养成编码习惯时,往往的确会有理性的思考,不光能说出所以然,而且似乎可以说服很多人,让大家觉得
“这样做很有道理”
甚至
“不这么做就是错的”
的判断。问题是:
关于这点,其实并不难理解,比如,假设我们想解决一个问题A,那么可能有1,2,3,……很多个解决方案,这些方案中可能会存在一些“同样正确且各有优缺点的”。
从另外一个角度来看,对于一个已知的“规则或者行为”,你往往可以找到不止一种原因和动机去解释它。
所以,结合以上两个方向的例子,我们要明白,很多事情都不是“非黑即白”的,尤其是编码规则的好坏、成因、收益这种极端主观的事情。
正因为评价它人代码的阅读代价太高,而凭借“眼缘”去评价它人“字太丑”简单且可行,因此,对很多人来说,追求“书法”而不是具体的“写作文能力”就成了“快速提高代码质量”的捷径——这里的代码质量,很多时候也仅仅只是“是否好看”了……
【C语言编码规范的“甜”和“咸”】
如果书法大家云集流派众多,C语言的编码规范也是有“门派”的,比如大家熟悉的Linux派、微软派……(此处省略1W字)。然而,无论门派多寡,其实都可以在一个“编码规范光谱”中为其找到一席之地。
在光谱的最左边是名为“纯粹追求美观”的极点、在光谱的最右边是名为“纯粹追求功能性”的另一极。实际上如今你所熟悉的编码规范,基本都位于两级中的某一位置。
对普通人来说,一般我们使用的编码习惯都处于这两级的中间地带,这不光因为很多时候我们同时会有“看着顺眼”和“提供额外信息”这两种追求,更主要的原因是:编码规范的本质是书法,对我们所使用的书法起决定作用的是“审美”,而每个人不同阶段的审美很难保持一成不变。当我们因为工作关系游走于不同的团队而被迫服从的编码规范时,久而久之……如邯郸学步,自己的“初心”可能早就被染成了“别人的颜色”……
【编码规范,怎么做才对?】
知道了编码规范的本质和原罪、讨论了编码规范的两个极端风格,那么我们普通人应该如何对待它呢?
【说在后面的话】
编码规范展现的是一种“认真的态度”,但它不是“能力和质量”本身。区别你要追求的是“书法的”编码规范,还是“思维的”编码原则。尊重他人从不贬低他人的编码习惯开始;团队合作从严格遵守编码规范开始。不要浪费太多时间,舒服就好。
如果大家感兴趣,后下次我可以简单的介绍一下我所使用的编码习惯,并尝试逐条解释规则背后的原因。