申明:因学识有限,某些见解和观点或有不妥,如有冒犯还请见谅。如需与作者联系,见文章底部个人签名处,乐于交流。Q群:210285832,欢迎共同志趣者交流。
【前言】
百度百科上说:“代码评审也称代码复查,是指通过阅读代码来检查源代码与编码标准的符合性以及代码质量的活动。”这篇百科的内容好像是几年前CSDN上的一篇博文,但不管他们怎么抄,代码评审大概就是这么个意思。
代码评审,没多大点事,貌似可有可无,但不管你怎么回避,确实不能也无法做到视而不见。
【代码评审的尴尬】
最典型的介绍代码评审的开展方法就是:搞个3、5个人,什么小组长、秘书、测试人员啦,然后开会什么的。于是代码评审变成了会议,开发人员多数是技术宅、务实派,比较反感这种貌似能解决问题却往往更加添乱的口水活动,于是这事自然成了形式。借用一网友的图片,会议的初衷是好的,但往往过于理想化:
图左 - 心目中的会议是这样的(图片来自网友博客) 图右 - 实际上会议却往往是这样
一直以来,个人对代码评审非常认同,身体力行,且行之有效。虽然实际推行的范围和力度根据实际情况有所保留,但这往往是基于团队成员的意识、开发目标类型的差异而作出的裁剪。
代码评审,其实是开发人员某种程度上追求卓越的一种体现,专业与业余的区别,往往在于细节。实现同样的需求,抛去什么高瞻远瞩的词藻,Martin Fowler写出的代码应该很容易就能跟一吊儿郎当的猿类区分开来,与其说是职业素养,不如说是习惯而已,敲出的是代码其实倾注的是感情。
网上偶尔出现的有关代码评审的讨论贴,往往充满火药味,争论的焦点莫不是:要不要评审、评审到底有没有好处、怎么评审。但对要评审的对象、所使用的评价目标、要达到的期望往往混为一谈,最终几百个回贴下来,还是得不出明确的结论。
【不要期望过高,务实是上策】
每个公司每个团队都有各自特点,作为政策推行者,尽信书不如无书,须要跳出书本理论,结合团队的实际,摸索出自已的方法。我始终认为,适合的才是最好的。
不要期望代码评审能一下子改变现状,但无疑,推比不推强,怎么推、推到什么程序度则另说。能看到效果,无论多少都是进步,循序渐进,贵在坚持。
不要心急,正如所有的政策推行一样,它应该是一个从弱到强、不断迭代的过程。先期重在培养和灌输一种意识,等大家的潜意识里基本认同后再进入下一阶段,否则还是先观察做细微调整后再说。切忌一蹴而就、强力推行,否则结果将很难看。团队对你的信任又要少一分了,管理者手上的牌其实不多,浪费一张少一张,团队成员的信任和耐心消磨一点少一点。
【解决之道1:先把代码按所属类型分类】
代码评审作为一项活动,从程序员的视角可以这样理解,它由3个组成要素:输入是“要评审的对象”、输出是“期望的结果”、而“评审判定的标准”就是你设定好的测试用例。
作为传统的软件开发公司,我是这么干的,把要评审的代码所属的工程项目分为3类:
[第1类] - 要进入公司可重用开发平台(通用类)的代码
描述:这些代码是公司历经多年的积累,逐渐提炼而成。它是公司技术资产的核心所在、立足之本。
评价标准:注释完备、代码结构能运用常用的设计模式、接口的设计合理且有一定的前瞻性。
前瞻性这个词很文艺,如何评价呢?我是这么理解的:前瞻性意味现在不需要的逻辑不代表永远不需要,但无需面面俱到,能解决绝大部分一般情况、也能解决少数的特殊情况、且能为无 法解决的情况提供一个规避方法为前提,因为通用类不是哪么轻易就可修改的。开发平台尽量物以类聚:完成同类或相似类别问题的代码尽量归类,尽量减小不同模块间的偶合,且能形成互相独立的子模块为最佳(你所抽取出来的子模块可应用于同类技术的各种场景而不限于该开发平台)——化整完零减小复杂度提高重用的可能性。
如果软件代码可以度量评分,如果最佳是100分,此类代码应至少达到80分及以上。你可能要问,这80分的标准貌似还是有点虚,确实如此,能把握到什么程度也只能全靠这平台的技术执掌人的个人技术修为了。
评审的主持人和参与者:这部分代码无疑对公司而言具有最高密级,不是所有人都能看到的,所以主持人最好是公司技术的最高级别负责人,参与者限于公司参与维护这类代码的开发者为佳,参与人员的范围越小越好,评审的强度当然是越大越好。
[第2类] - 要进入公司标准产品的代码
描述:此类工程不仅可能会作为公司的直接营收来源,它还会作为客户定制项目的基础而存在。
它的质量首先由前面的基础开发平台进行了保证,要评审的代码应该绝大多数都是业务相关代码,此类代码不求技术高超,但求代码规范,但一定的扩展性等问题也是不可回避的——它可能会决定定制项目的开发难度(甚至开发的可行性)。
评价标准:注释较完备、关键业务及逻辑必须进行完善地注释(甚至要能关联到原始需求,比如JIRA中的Issue等)、任何被调用2次及以上的代码必须要抽取成单独的方法或类等等、规范的编码习惯(那大段的空白、连缩进都没做好的代码,显然不能避过)、各种代码应按业务或一定的逻辑进行分包归类、各种代码的命名(包括类名、方法名)也应遵循一个大家一致约定的命名规则(遵循一致的命名规则和约定就跟为什么那么多公司一定要用各种框架的道理是一样的——提高代码理解的互通性、降低上手门槛),尽量做到见名知义。
这些代码不求技术高超,但求代码规范,代码质量应能达到60分及以上(至于何为60分,真没法度量,全凭技术执掌人的技术修为和直觉了)。
评审的主持人和参与者:这些代码也属公司有重大价值的资产,因而也是不应大范围扩散,公司技术负责人、产品技术负责人来保证所有代码的整体框架和质量、各参与开发的开发者作为评审参与人即可。
[第3 类] - 基于标准产品的以客户定制为目标的商业项目
描述:此类项目是公司的营收来源,代码的质量倒是其次,关键在于成本、交付期、交付质量等几方面的博弈和平衡,在资源充足(这个资源是广义的:比如时间、金钱等)的情况下当然项目的代码质量越高越好,但很多时候没有必要。
评价标准:在时间充足且考虑到该项目还需要后期维护的情况下保证代码没有明显缺陷、代码编写都较为规范、一般业务注释较齐备、关键业务注释较详细也就可以算得上高代码质量的产品了,但如果成本压力大、交付期很紧的情况下,则具备一定的应用品质且能尽快交付为佳,至于代码质量则排在后面再考虑吧,毕竟所谓高质量代码是为了后期的维护方便,在目前条件受限的情况下,先满足最基本的要求才是上上策。
评审的主持人和参与者:公司最高技术负责人作为外围推动者,项目组的最高技术负责人为主持者,具体开发人员为参与者,尽量做到签入的代码都是经过评审的(至少要经过项目技术负责人的检视,至于过程有是细致还是精糙,则应依情况而定,做总不比做强)。
【解决之道2:润物细无声】
对于未知或暂时未知的事物,人都有一种或多或少的恐惧感。就拿学习一项新技术,刚听到这个名词的时候,心里琢磨:这东西貌似不简单。忽然有一天公司急用,心里咯噔一下——慌了,接下来脑海里必然出现3个字——“怎么办?”但当你真正花点时间仔细琢磨并逐渐入门之后,恍然大悟——“原来如此!”顿感亲切无比。
代码评审也一样,没必要成天把名字挂在嘴边,说白了不就是看代码吗。作为技术管理者,就像给闹钟紧发调,今天紧一点,明天再紧一点,后再更紧一点,逐渐从点到面,积少成多,等大家都形成了习惯,生米也成熟饭了。至于它叫不叫“代码评审”,还有关系吗?关键在于,目的达到了,而且在大家不知不觉中,推行几乎没阻力。且张弛有度,最近一段时间貌似路走的有点偏,稍微调整一下,团队实在无药可救则慢慢撤下也是不知不觉。
推行之初又是开会,又是讨论的,这调定的太高,真若操作不当,如何下的了台?作为技术管理者保持一定的权威还是有必要的,无论事大事小,搞砸了,必然在下属或团队成员面前形象多少受损,得不偿失。
【解决之道3:我的实践】
代码评审,就跟公司里的很多政策一样,不推不行,强推更不行,没人支持的政策迟早沦为形式。
代码评审与其说评的是代码,不如说是评责任心,责任心是一个人的职业操守要素之一。没有责任心的人烂泥糊不上墙,你休想改造他(所以这也扯到招聘的事了,人品是前提,其次再谈技术,关于招聘的问题以后的文章里再详细讨论)。
如果在逐级下推的过程中遇到不理解或不配合,也无需灰心,先不要强行下推,放放看看,柿子先捡软的捏(嘿嘿),这些意识迟早会传染给这些目前还啃不下来的骨头。
代码评审,其实讲究的是从自我做起,每个人对自已严格要求这事也就省不少了。所以根本问题还在于,严格要求应是这种团队的基本文化。换句话讲,自由散漫的团队,代码评审这活似乎有点不搭调,你说呢?还不如先把基本团队精神确立,再来谈也不迟。
【解决之道4:评审过程中不可忽视的原则】
1)代码评审,它只是开发人员的事:
很多文章里写到,要把测试人员纳入进来,很多理论里其实又讲要让测试人独立于开发技术细节之外,从而能从不同于开发人员的视角找出bug,这样的言论无疑是矛盾的。至于测试人员怎么安排,不在本文讨论之列,但代码评审这个事,似乎真与测试人员没多大关系。开发人员保证代码的质量,无可厚非,而且能一定程度提升他们的责任感,而且面对代码这本身就是他们的长处,专者尽其才,方可发挥最大效力。
2)代码评审,最好不要跟业务挂上勾:
首先说明,评审过程中能跟业务挂上勾其实是最能达到评审效果的方式,但缺点在于,评审人员读别人代码的前提是要先理解业务逻辑。 这要求就高了点,干过开发的都有体会——写代码往往比理解业务要容易(但也不尽然),如果要把理解业务作为前提,与其说是评审代码,不如说是学习业务。我估计这事十有八九要遇到不小的阻力,开发人员都很懒(呵呵),能省则省,能避就避,让他们干完本职工作还得额外痛苦一回,你说他乐不乐意?
3)做这事前,最好得到直接上司的理解:
如果你是公司CTO或技术总监倒问题不大,但如果你是项目经理或项目组内的架构师等,则干这事你得掂量掂量,如果你直接上司与你一拍即合那当然没话说,如果上司自已对这事也不痛不痒,甚至公司从上至下的技术文化就是散漫自由型,那你还是趁早收手做好自已为上,这爹不痛娘不爱的事,呵呵就不往下说了。。。
4)对事不对人:
那就是评审的目的是为了提高代码的质量,而不是找谁的茬,这种心态必须贯穿始终。
5)尽量避免相同或相近水平的开发者互审代码:
两个半吊子,自已的见地和知识水平本身就有限,他们作为观察者进行学习才是最要做的事,真要让他们参与进来那就不太靠谱了:因为他们自已都不太不相信凭已之力能改变别人的代码质量,你觉得他们会正确认识这件事吗?这事还不得慢慢黄了?所以评审的主持者或评审人应至少是技术相比高一层次的人员,否则不如不做。其实代码评审就也是一个学习的过程,传、跟、帮、带,这事靠谱。
6)签入的代码尽快进行评审:
代码是有版本和时效性的,坏的习惯可以传染,这次没注意到的坏毛病经过漫延往后很可能就泛滥了。尤其在项目组组建的早期新进人员较多的情况,尤其要尽快进行——即时纠正不良习惯、约束大家形成一致的步调。尽快查复、随时随地复查、非正式复查等等形式,总之是要把复查的工作量化于平时的工作中,避免积少成多,到最后积压成不可能完成的负担。其实好的习惯也是可以传染的,在项目早期纠正了一些不规范,越往后期这样的问题会越来越少,从而形成良性循环。
7)评价标准一定要有:
标准很重要,对于公司核心平台标准应由技术负责人个人把握(那就得看他的技术修为了),对于产品和项目则应有公司统一的基本编码规范和一些约定俗成的东西等,一些典型的优质产品或项目可以作为标杆,供学习和培训用,没有灯塔,如何前行?
8)标准一经确立,都应无条件遵守:
一旦确立了标准,则任何有关人员都应遵从。标准可能有缺陷,你有权提出改进,但一经确认,就得无条件遵从,这就是所谓的管理有方了。
【解决之道5:借助工具,放大生产力】
努力很重要,方法更重要,而工具的使用往往是方法能否成功落地的关键。经过较长一段时间的实践,目前主要使用了以下这些工具,效果都还不错:
1)JIRA:作为项目管理工具的核心,它可以管理需求、任务分配、任务跟踪、结果统计、版本发布、与Fisheye/Crucible组合,可很好地实现工程代码的变更和代码评审,非常好用;
2)Greenhopper:它其实是JIRA的一个插件,适合于敏捷开发团队使用;
3)Fisheye:它是JIRA同一公司下的产品,可以很容易获知整个工程里任何一个资源的变更情况,与Crucible同时使用可以很好地生成代码评审活动;
4)Crucible:同Fisheye一样,同一家公司的产品,代码评审利器;
5)IMO:国产企业办公用的即时通和协同办公软件,用起来不错,更重要的是免费,貌似还跟企鹅吵过架;
6)知识库Discuz论坛:其实另一名为Conflurence的产品也是JIRA同一公司产品,可以很好的集成。但经过评估,最终还是采用国人开发的免费论坛,好处是对国人而言实在是太熟悉了,推广难度自然小许多。这东西用的好的话从某种角度讲比Conflurence要强大太多了:权限控制还不错、知识分享、文档资源归类下载、各种自由讨论等等,还可以鼓励个人有时间写写日志(密送或公开),对公司范围或团队范围内的交流有很大的帮助。
以上这些工具,首先申明不是为它们作广告,如果你这么感觉请忽略之。不一定适合所有团队,还是那句话,适合的才是最好的。有时间还想针对这些工具的安装和使用写写文章,不得不说,安装、使用、组合的过程确实有点折腾人,但好东西谁想错过啊,呵呵。
【感悟】
很多时候,当你低着头一直往前苦苦找寻你的答案,却往往得不到你想要的,当你担起头准备放弃的时候,回头一看,哦,原来答案就在起点不远处。化繁为简,跳出固有思维,往往答案就在你的脚下。。。
附件1:使用的JIRA系统
附件2:使用的Fisheye+Crucible系统