说说Code Review

过年回来后开始接手管理一个技术团队,这个团队去年一年基本上都在赶项目,晚上常常加班到晚上十点之后,因此代码质量不用多说你们也能想获得。前几天跟你们开会,我提出来从下个版本开始要作code review,有个同窗问到「那不会浪费不少时间吗?」,我告诉你们「会花不少时间,但不会浪费不少时间」。由于这个团队里同窗以前没作过code review,因此准备下周给你们作一下分享告诉你们应该怎样作,因而今天花点时间把脑子里的想法掏出来梳理梳理。性能

1、目的是什么

作任何事情都要有一个目的,那么咱们作code review的目的是什么呢?原本开发工期就很是紧了,特别是身处中国这个大环境下的互联网公司,老板巴不得要你二十四小时连轴转,为何还要花那么多时间去作code review呢?我认为code review的目的在于提高代码质量。单元测试

前几天看了篇文章,里面有这么一段对我触动很大:测试

在这种业务需求紧张的模式下,Facebook一些开源技术方案是如何产出的,是非业务团队专门作的么?
我想说的是即便业务需求紧张,也同样把代码好好写好,另外有牛逼的tech lead和严格的code review,总的质量也不是不好。国内有一点很很差:常常没有code review;并且技术人员观念很差,把要写的代码当差事,只要能完成能用就好。因此就愈来愈操。
(Code reivew一直是硅谷一线互联网公司的质量控制法宝,从Apple到Google,从Facebook到如今的Airbnb和Uber。可悲的是,国内的人都太聪明,以为这东西没用繁琐,并且减慢开发速度。有时,咱们就是太过聪明。)编码

因此咱们不要老是拿没时间来当作借口,若是对代码质量没有必定的追求,给再多时间也是没用的。业务需求紧张须要经过提升工做效率来解决,而不是不花精力提升代码质量。另外,站在一个项目的生命周期来看,写烂代码真的会比写好代码花的时间更少么?翻译

2、好代码最重要的特征是什么?

既然作code review的目的是提升代码质量了,那么什么样的代码才能算是好的代码呢?最开始这个标题我写的是「什么样的代码才是好代码?」,后来我想了下这个问题太大,我没法对「好代码」简单的下一个定义,真正讨论起来估计得单独写一篇文章了,因此先按住这个话题,换成简单的「好代码的最重要的特征是什么?」。日志

我觉着好代码最重要的特征是可读性强,这样才能让和你协做的同窗以及将来的你本身可以不用想太多就能看得懂,毕竟花在维护代码上的时间要远远超过写这段代码花的时间。每新增一行代码就会多增长一份维护成本,而可读性强的代码能够把维护成本降到最低。code

那么咱们怎样来定义这个可读性强呢?每一个人都有本身的标准,怎样才能在团队里让你们都承认呢?微博的一位工程师在他写的《关于烂代码的那些事》这样写到:对象

在不少跟代码质量有关的书里都强调了一个观点:程序首先是给人看的,其次才是能被机器执行,我也比较认同这个观点。在评价一段代码能不能让人看懂的时候,我习惯让做者把这段代码逐字翻译成中文,试着组成句子,以后把中文句子读给另外一我的没有看过这段代码的人听,若是另外一我的能听懂,那么这段代码的可读性基本就合格了。
用这种判断方式的缘由很简单:其余人在理解一段代码的时候就是这么作的。阅读代码的人会一个词一个词的阅读,推断这句话的意思,若是仅靠句子没法理解,那么就须要联系上下文理解这句代码,若是简单的联系上下文也理解不了,可能还要掌握更多其它部分的细节来帮助推断。大部分状况下,理解一句代码在作什么须要联系的上下文越多,意味着代码的质量越差。
逐字翻译的好处是能让做者能轻易的发现那些只有本身知道的、没有体如今代码里的假设和可读性陷阱。没法从字面意义上翻译出本来意思的代码大多都是烂代码,好比“ms表明messageService“,或者“ms.proc()是发消息“,或者“tmp表明当前的文件”。blog

我很承认这个说法,在这个基础上,我一直坚持认为虽然一个能把一件事情描述清楚的人写的代码不必定可读性强,可是一个没法将一件事情描述清楚的人写出来的代码可读性确定不好。生命周期

3、那么,该怎样作呢?

说了那么多了,具体怎样落地到现实工做中呢?即便按照前文所说的把代码逐字翻译成中文讲给其余同窗听,也同样可能因为认知问题致使对方听不懂,好比你认为很基础的概念可能别人并不了解。因此我认为你们要遵循一些基本原则,这样才能有效的沟通。

3.1 SOLID原则
这是面向对象的五条基本原则,我列在下面,在这里就不展开来讲了

  • Single responsibility principle

  • Open/closed principle

  • Liskov substitution principle

  • Interface segregation principle

  • Dependency inversion principle

3.2 Don’t Repeat Yourself
通常对这条原则的理解是对于一样的功能不要直接copy原来的代码,而是要抽象出一个公用的方法。可是实际上对一样的功能用不一样的思路或者代码去实现也是一种浪费。好比常见的日志处理、异常处理逻辑。

3.3 Prefer Composition to Inheritance
这条原则跟前面提到的OOP的SOLID原则里面的Interface segregation principle有点重合之处。随着业务需求的不断迭代,小的组件逐渐会演变成大的组件,在这个过程当中驾驭的难度会逐步提高,而若是在不断迭代的过程当中不断抽象出小的组件,则能够在业务功能复杂的同时保持代码的简洁。好比无论是飞机仍是汽车火车都是会移动的,而我在使用时只需知道这个对象是可移动的便可,至于这个对象是飞机仍是汽车我并不关心。

3.4 编码规范
这个很少说了,能够采用一些行业里优秀的编码规范。可是要注意的一点是规范的做用是保持项目编码风格的统一,不要在规范上作无心义的争论。

3.5 若是不具有抽象的能力,那就重复吧
这是一个比较残酷的也比较常见的现实,看了一大摞的书废了老大的劲终于抽象出了一个组件,可是最后的结果倒是加大了维护成本。因此若是你觉着没法很好的去抽象,就直接用最粗鲁的重复代码吧,毕竟这样别人还能看得懂,比抽象出来后还要再写一大堆的if else好多了。

4、技术以外的tips

在技术以外还有一些要注意的点,首先最重要的就是要有一个开放的心态,review的是代码,而不是具体的人,不要由于对方的review而感受羞耻,固然也不要进行人身攻击。

其次,要把握review的粒度,不要一下发起一个很是大的PR,这样会给review的同窗特别大的压力。好比一个PR里最好不要同时既有重构又有新特性的开发,或者憋到最后这个版本都要开发完了才一块儿提交一个PR。review应该是在平时的工做中持续进行的,而不是相似里程碑的总结之类的东西。

第三,code review不该该承担发现业务逻辑错误的责任,也就是日常咱们所说的bug,bug应该由单元测试、功能测试、性能测试等方法来保证,不要赋予code review太多的责任。

相关文章
相关标签/搜索