据说,赵国的首都邯郸的人走路的姿态很好看,动作非常优雅、轻快。 燕国有一个少年听到这个传说,非常羡慕邯郸人,就走了很远的路去赵国,想学习邯郸人走路的方法。刚开始,他整天站在街头,仔细研究每个人走路的姿态,再慢慢模仿他们,可是都没有成功。后来,他想可能是受到过去走路习惯的影响,所以,他决定要忘掉以前走路的方法。从那时候起,他更专心研究邯郸人走路的姿势,不过,再怎么努力他还是学不会,最后他只好放弃。可是,因为他把以前走路的方法忘得一干二净,已经不知道该怎么走路,只好一路爬着回去。 http://www.hydcd.com/cy/gushi/0236hd.htm
【编码规范的本质是什么?】
编码规范是在一定范围内强制推行的编码习惯;这里的编码习惯通常来自于对团队有控制力的一个或者少数几个人。
这里,你会很容易注意到三个关键字:“一定范围”、“强制推行”和“编码习惯”。抓住这三点,编码规范的本质就像“任意不在同一直线上的三点确定一个平面”一样——没得跑了。
首先来说说这个“编码习惯”,其实很好理解,它就是字面意思——一个人写代码时候的某种习惯,高情商叫风格,低情商叫“我就爱这么干,别问我为啥,我要么不知道,要么等我编个理由告诉你”。总之呢,编码习惯带有强烈的主观性、基本上可以认为缺乏强有力的客观依据,在稳定性和一致性方面其实就是水中花镜中月——不能说完全没有,只能说毫无可信度。
不信么?今天你看了一个大牛的代码,觉得:
“哇!好牛逼”,
“大牛这么做一定有什么深意”
然后不自觉的就学着人家的编码规范来了。过了几天,你可能又碰到了另外的大牛,或者是什么明星开源项目……咋说呢……如果用男女关系来形容兄弟们的行为,那就是妥妥的渣男/渣女——没得洗。
你跟我说说,哪儿来的稳定性和一致性?还不如先问问“你是谁的粉”比较靠谱。
很多时候,一个程序员自己的编码习惯可能一辈子都没有鲤鱼跃龙门——成为编码规范的机会;但如果有朝一日,你满足了以下两个条件,你的编码习惯就是妥妥的编码规范了:
拥有了一个完全由自己掌控的团队或者项目;
拥有了执行决定的强制力;(比如KPI审核,扣工资之类)
【编码规范的“原罪”】
无论是编码规范还是编码习惯,都只跟描述“你写字丑不丑”、“漂不漂亮”的一个“主观性非常强的”、甚至还带有“艺术性玄学”的评价标准有关;
我们日常写代码其实可以类比为写文章,这意味着:
你可以用非常漂亮的手写体写出狗屁不通的文章;
你也可以在赶时间的情况下,用一种只有自己看得懂的方式,快速而高效的写出优秀的作品;
书法除了草书,往往暗示着——费时间;何况草书往往暗示着,除了那几个评论家,普通人基本看不懂。
书法好坏和写文章所需的遣词造句的技法,以及文章整体的修辞、结构安排完全无关。
原罪1:肤浅引战的导火索
……读懂一段程序,实际上就是要通过死的代码逻辑去反推模块构作者的思维,这是一个逆向过程,这是一个人与人之间用代码进行间接交流的过程,当逻辑本身较为复杂时,显然比将自己的思维直接翻译成程序(重新开发一个)更为困难。
傻孩子,公众号:裸机思维真刀真枪模块化(1)——一本糊涂账
这里,我提到了一个关键的事实——阅读他人代码是非常耗时和困难的。这样的事情无时无刻不在发生:当我们拿到一段代码时,想通过了解它的内容来判断好坏几乎是不可能的——这不光意味着你要花费时间去阅读它,可能你根本不想去阅读,或者根本没有这样的时间去阅读。此时,要想判断一段代码的好坏就只能通过非常表面的东西来进行了——是的,就是看你写的字漂不漂亮。
如果明确知道这是“名人大家”的作品,或是出自某个大厂的作品,事情就变得非常简单:只要学习历来文人是如何在同行面前显示自己学识渊博的方式——花式吹就行了。
如果要评价的对象是同辈的作品,或是某个来源不明的作品,大家就一下开始“审慎起来”,仿佛瞬间化身为严肃的艺术评论家——在严肃而充满理性的批判声中,自己“高超水平”和“恨铁不成钢的惋惜”跃然纸上。
原罪2:似是而非
这些“严谨大佬”们做出思考的背景是不同,而人们讨论和传播编码规范的时候往往会丢弃这些背景信息而将其“泛化”——或者说无限制的扩大适用范围;
很多作为某一编码规范规则在背后的支撑逻辑,我们可以说它是“正确的”,但遗憾的是,它的正确“并不意味着其它做法是错的”——事实上,有很多规则所服务的逻辑实际上存在很多“同样正确、且平等的正确的竞争者”。
编码规范的信徒们,往往视其它规范(甚至是某一个规范的变种)为异端,定要除之而后快,表现为与他人进行无意义的论战、不说服他人加入自己的阵营就决不罢休,甚至上升到人身攻击等等……
原罪3:遮羞布
【C语言编码规范的“甜”和“咸”】
“纯粹追求美观”,顾名思义,代码写出来要眼睛看着舒服。需要特别强调的是,这里的看着舒服与“代码的可读性”完全是两回事。
纯粹追求美观的杰出代表是Linux编码规范——它所追求的是纯粹小写所带来的那种和谐而统一的美;它基本不对函数、变量名、类型名做任何的区别(甚至是非常数的宏);为了解决小写单词缺乏“节奏”的问题,而在单词与单词之间简单的引入“_”完事。
这种美学就好比最优质的牛排,只需要辅以简单的海盐,进行简单的烹饪就能发挥牛排最原始的美味;这就好比,新鲜的生蚝,只需要挤上几瓣柠檬就可以释放出最大的鲜甜……
正是由于Linux这种纯粹追求视觉上的和谐而不“诡辩”自己有如何功能上的便利,受到众多“返璞归真”老鸟的狂热追捧——我要的就是简洁的美,其它都在我心间。
“纯粹追求功能性”,顾名思义,就是以牺牲一定程度的“美感”而换取某种功能上的便利。实际上,完全牺牲美感的编码规范几乎没有,但很多商用协议栈的编码规范或多或少都有着明确的功能追求。
典型的是匈牙利变量命名法,它的特点是为每一个变量追加必要的类型信息,从而提高变量名的信息携带量——最终尝试提高代码的可读性。在Linux玩家的眼里,匈牙利是真的丑;同时作为一个如入鲍鱼之肤久而不闻其臭的匈牙利变量命名法玩家,我也只是“习惯了”这种用法,你要说我觉得它有多美,那也绝对是扯淡。有意思的是,匈牙利变量命名法往往会与驼峰命名法搅和在一起,这让纯粹的驼峰信徒颇为不爽——因为驼峰可以说是“美的”,但你非要粘上一些类型标签——就好比在布丁的蜂蜜浇头上发现了苍蝇一样恶心。
公平的说,匈牙利所附加的信息的确有助于提升代码的可读性。至于美不美,可以完全抛在脑后。
另外一类“追求功能性”的编码规范就是各类DSP、视频、音频、数学相关的协议栈,它们纯粹为了方便API的使用,尝试在变量、函数以及类型名称上附加大量的信息,以描述API的参数类型、函数所代表的的运算功能、以及其它相关专业方向才会理解的特性属性等等——这样的信息追加,造就了犹如喀斯特地貌一样的奇观——用是好用,美不美,就不好说了。这类协议栈的典型是鼎鼎大名的Dolby的音频库。
【编码规范,怎么做才对?】
字写的好看,是一种展示“认真态度”的方式;努力写出漂亮的代码无可厚非;
切记不可喧宾夺主,在本意是追求“如何写出优秀作文”的时候,注意力过多的被“如何写出漂亮字”的编码规范所抓住,浪费不必要的时间;
不要把编码规范上升成宗教信仰——哪怕你是无意识中这样做的;
记住:优秀的程序员可以在任何编码规范上随意切换——这是你游刃有余的一种表现。
如果想讨好一个人,赞扬他的书法;
如果一个群里的人让你讨厌,可以在退群之前,可以故意挑起关于编码规范孰优孰劣的宗教战争——如果碰巧他们都是同一个宗教的信徒,则尝试发起关于“怎样才是正统”的讨论。如果你喜欢一个群,就切记不要这么做。
在自己可控的范围内——比如自己的开源项目里,随意的使用自己的编码规范。如果要跟他人合作,最好写清楚自己的习惯,并且保持包容的心态——因为,请记住:
编码规范的制定者往往会被所有人盯着,等着你的永远是“你自己的规范你自己都没遵守”,而不是“你的规范真好”的赞赏;
对任何你订立的规则,你写下来的只是你心目中的“默认情况”,而没写来的是大量你自己觉得合理的“特殊情况”——在你心中,除了“少数”特殊情况外,我们都应该按照“默认情况”来处理——可惜,这里的“少数”往往超出你的想像;
不要认为别人质疑你的编码规范就是在骂你、质疑你或者找茬——哪怕大部分情况都是这样;
同理,尽可能遵守它人的编码规范,来展示自己对它人的尊重。看到“特例”不妨一笑了之。
干点正事吧!
【说在后面的话】
如果你喜欢我的思维、觉得我的文章对你有所启发,
请务必 “点赞、收藏、转发” 三连,这对我很重要!谢谢!
欢迎订阅 裸机思维