一个大型的项目中通常有好几个开发人员,有些人的代码风格就是不一样。在阅读整个项目源码的时候显得比较困难。对于这样的情况,有必要让项目中所有人都统一遵循的代码风格吗?
注:这里说的代码风格不同于代码规范。代码风格多指缩进使用空格还是tab这一类的问题。
一个大型的项目中通常有好几个开发人员,有些人的代码风格就是不一样。在阅读整个项目源码的时候显得比较困难。对于这样的情况,有必要让项目中所有人都统一遵循的代码风格吗?
注:这里说的代码风格不同于代码规范。代码风格多指缩进使用空格还是tab这一类的问题。
缩进/tab/换行等排版风格应当统一,所有人都这么说,但个人感受对非开源的商业项目来说重要性不那么高(除非项目成员都有代码洁癖)
另一类代码风格比如整体结构、异常处理、分装颗粒度等这些更加需要统一,虽然统一的难度比排版风格难很多,但统一带来的好处(混乱带来的坏处)也大很多。题目中已经提到的代码阅读困难实际上正是项目崩溃的重要信号:在阅读困难的代码上工作,程序员往往选择patch/hack的编程方式,使代码越来越难以维护。
排版混乱的项目如果阅读困难好歹很容易用个脚本就能拯救。但一边面向对象消息驱动,另一边面向过程配置驱动,每个成员各自有自己的一套异常处理风格的项目,仅是想象一下我就感觉脑内有马赛克出来了……
建议:团队需要花一些时间开会大家统一代码风格,写一份文档把会议(投票)结果记录下来,然后拿着这份文档互相CodeReview保证风格统一,乱写的拉出去弹丁丁
规范里肯定包含了缩进的要求呀,用什么符号缩,缩多少,甚至包括括号之前之后是否有空格,大括号是新行还是旧行,细致的规范保证了协同工作时候互相阅读没有障碍、很多语言甚至有检查风格是否规范的工具。。。帮助项目程序员在提交代码之前自行检查:)缩进是非常有必要规范的,因为有人喜欢用空格,有人喜欢用 tab, 他们修改彼此 的代码时, 就容易出现“删一下,还是删四(或者八)下的问题”
统一是有价值的,而且价值很大。
在此想到了一篇文章《Google为何要执行严格的代码规范》中有这么一段话:
在谷歌,我可以查看任何的代码,进入所有谷歌的代码库,我有权查看它们。事实上,这种权限是很少人能拥有的。但是,让我感到惊讶的却是,如此多的编码规范—缩进,命名,文件结构,注释风格—这一切让我出乎意料的轻松的阅读任意一段代码,并轻易的看懂它们。这让我震惊—因为我以为这些规范是微不足道的东西。它们不可能有这么大的作用—但它们却起到了这么大的作用。当你发现只通过看程序的基本语法结构就能读懂一段代码,这种时间上的节省不能不让人震撼!
这个要分情况:
我是来发出一点不同/奇葩的声音的。
我认为:代码的缩进排版风格完全没有必要统一!
不过且慢,前提是你的团队成员都使用了有高级代码格式化功能的IDE,并且项目版本库设置了提交前自动格式化代码的hook!
试想一下,你将自己的IDE配置成自己喜欢的排版风格,然后打开代码文件时,IDE都自动将代码重新格式化成你的prefer风格;你编辑好代码保存之后,提交到版本库,比如Git或Hg,并且在版本库上设置了一个before commit的hook,对所有要进入版本库的源代码都按照一个统一的排版方式重新格式化后再提交到版本库。这样,每个人都可以使用自己喜欢的代码排版方式Coding or Review,也不会影响其他人。(之所以要在代码进库之前再format到标准格式,是为了便于diff,目前基于程序语义的diff/merge工具也没被开始应用——所以会有这种因为diff/merge产生的BUG:http://coolshell.cn/articles/11112.html)
但那只是想象,我从来没听说过哪个团队使用这种方案。因为这个方案有这样几大阻碍:
go format
。但对于Python呢?它将缩进当成语义的一部分啊。对于Java,要是工具处理缩进错了仅仅导致看起来不爽而已,Python自动缩进不正确的话,代码就彻底错了啊!而且有时缩进错误会成为一个潜在的Bug、而不是直接报SyntaxError!或许你会说,我们团队又不用Python这种2B语言,我们就不用这样提心吊胆了。最后,你只能去墙角默哀!
如果这样的工具(代码排版格式化、甚至结构化编辑的IDE)在业界受到广泛支持与应用,我想我们就不必在缩进是用空格还是Tab的问题上争论不休了.假如能根据代码语义进行格式化的IDE和工具链成熟了,我们就可以不要脸地在代码中混用Tab和Space了,呵呵。
在IDE还没有对变量名函数名重构功能(将一个函数名重命名后,IDE自动将项目中所有调用到该函数的地方的名字也改成新的名字)的时代,软件项目中就有各种历史遗留的命名问题。你发现项目中一个函数的名称拼写错了有歧义,想要修改正确,但好多地方都调用到了这个函数,没有IDE的refactor功能帮助,谁敢动这大段代码啊,改漏了出错了可承担不起啊。(直到golang才终于有机会将creat拼写错误修正了)。
所以,结论是,囿于现状,团队成员必须都使用相同的代码排版规范!
再补充说说命名规范。
和代码排版问题不一样,这个东西肯定没有办法用IDE自动格式化。但从另一面来看,不但团队需要一个命名规范,而且,不同的语言、不同的开发框架,其规范应该是近似固定的。
可见,对于命名规范问题,其实根本不是什么强迫别人遵守什么代码规范,而是为了将代码语义最佳化,每种平台或语言都形成了自己的一种命名传统(Naming convention)。假如一个Java程序员要是给每个变量名都像
int i_count;float f_percent;
这样加个下划线和类型提示,要么不会用IDE,要么就是有病,这种将其它平台或语言上的习惯带到Java上肯定不受人待见。当然你会遇到有些语言中变量方法名既流行camelCase又流行under_score,比如Python、PHP之类的,那是,因为,它们本来就是一个不规范的语言,它们的标准库的命名本来就很不一致(又黑了一把)!如果命名规范的不同 不影响程序的正确性或语义,那最后只有一个标准规范:就是统一。
在同一个项目中始终使用同一个规范。你不能因为下划线在键盘上难输入或是你的Shift、CapsLock键坏了就坚持打这个反传统的圣战。
多关心关心程序的正确性及表现力,给函数起一个易懂且具概括性的名字,是under_score还是CamelCase,并不很能体现一个程序员的执著审美与品味。