关于代码评审

words: 2k    views:    time: 6min

很多团队都有这样的问题,开发人员水平不一,想法不同,代码各有各的风格,Review起来又费时费力,感觉很难让所有成员保持统一风格。所以参考他人的一些经验,也总结了一些关于代码质量管理与提升的思考。

评审的目的

代码评审的主要目的是希望随着时间的推移,代码能够越来越健康,而不是放任其腐化下去,越来越混乱,以至于最后不得不推倒重来。通常情况下,代码的质量都容易随着时间越来越差,尤其是在项目需求有明确时间限制,让开发觉得不得不采取一些投机取巧的方式才能完成任务的情况下。

评审的另一个目的是希望能提升技术氛围,鼓励团队内的技术分享。团队人员有进有出,有一些正能量的人自然也有负能量的人,这都很正常。但不管怎样,我们相信做技术的人都有意愿提升自己的技术能力,通过分享各自擅长的领域,互相学习来了解彼此,提升团队凝聚力和整体水平。

评审的原则

评审并不是要求开发者打磨好提交中的每个细节,而是会根据项目进度和开发给出的意见重要性,适当权衡要求。最终目的是通过评审能提升整个系统的可维护性、可读性以及可理解性,而不是追求完美,也没有完美无缺的代码,只有越来越好的代码。

  • 技术和数据高于意见,鼓励质疑,尊重个人偏好;
  • 遵守开发规范,保持代码风格,关于风格应该与现有的保持一致,如果以前没有风格,可以就按作者的风格来;
  • 软件设计从来不是纯粹的代码风格或是个人偏好问题,它们是基于一些应当被权衡的规则而不仅仅是个人倾向;

评审的关注点

评审中很重要的一点是要了解清楚开发者提交变更的意图,并确认其意图与实际需求或设计的吻合程度。代码质量同样重要,理想情况下,自然是希望代码具备高内聚、低耦合的特性,同时又能满足需求符合设计。

实际项目中,可能由于各种原因会适当放宽要求,但至少还是会要求保证代码结构清晰,逻辑层次分明,风格应该尽量的简单直白,符合直觉,让别人能比较容易地明白意图。

  • 设计良好: 首先保证良好的设计,不管是需求设计还是存储设计、接口Api、或是算法流程,在实现上也应该保持与设计一致;
  • 提交说明: 描述清楚提交的内容,应该言简意赅,并保持语义完整。可以参考git提交规范,尽量一次变更只做一件事情;
  • 文件目录: 结构层次清晰,可以参考一些规范,比如MVC和DDD;
  • 变量命名: 语义清晰,包括文件、库表字段、以及类、方法变量等,通过命名能明白其意图,以及所属归类;
  • 代码风格: 保证格式化,段落层次清晰,可以通过一些空行,方法拆解,来体现逻辑的层次感;鼓励在风格上提出一些改进建议,但也要避免吹毛求疵。
  • 职责单一: 不管是类、接口、还是方法的定义,都应该有自己对应的角色或者职责,只是维度可能不一样,应该保证它们的分工明确,职责清晰;
  • 复杂度: 除非特殊处理,单个类或方法的复杂度不应该太高。设计上也应该避免引入不必要的复杂度,我们鼓励通过设计来提高可扩展性,但不应该为了扩展一些不存在的场景而过度设计,需要甄别引入的复杂度是否值得;
  • 代码注释: 准确必要的注释(错误的注释不如没有,不必要的注释反而增加维护负担),尽量使用类注释,接口注释来代替行注释;
  • 单元测试: 必要的单元测试,比如对于一些关键的api或流程算法,应该提供充分的用例测试;
  • 线程安全: 如果涉及到可变共享资源的访问,需要格外留意线程安全问题;

评审的步骤

这里主要针对的是线下组织的评审会议,为了避免会议中的讨论走题浪费时间,所以我们应该在会前明确好会议的主题流程

  1. 评审范围,首先明确改动范围,比如一次变更提交,某个功能或者模块;
  2. 需求背景,说明改动的意图,说清楚做了什么,期望达到什么目的;
  3. 设计思路,怎样做的,说明设计意图;
  4. 代码实现,对照设计说明实现细节;
  5. 遗留问题,在设计实现过程中是否还有一些未完成的Todo,或者一些妥协;
  6. 评审意见,可以在git上以Issues的方式提出意见,由评审人落实修改;

代码评审的一些实践

  • 代码检查

对于代码规范,可以使用sonar进行扫描,但这个方式的问题是太过滞后,需要质量人员去跟进和推动,并且效果也不是很好。因为大多开发都有一种习惯,如果代码写完上线之后没有问题的话,他们很少会主动去优化代码,即使你告诉他扫描有问题他也会有各种理由推脱,虽然你可以通过kpi等管理手段强制要求修改,但肯定不是一个好的方式。

可以使用git + checkstyle或fingbug等工具插件,来前置检查点帮助开发人员在开发过程中就发现问题并进行解决。在Maven工程中,也有代码检查相关的plugin,比如pmd插件结合阿里开发规范,如果不符合规范直接拒绝编译打包。

  • 代码提交

作为开发,写清楚提交描述是必要的职业素养,至于一些不按照规范来写的开发可以直接对他们提出要求。

可以将提交记录与具体的开发任务关联起来,比如在comment中添加项目管理工具上的需求或问题单号。如果想避免开发人员忘记,可以通过一些工具在提交时进行检查,比如git的hook机制在代码提交前后提供了一些钩子,pre-commit或commit-msg,可以用来控制提交允许或拒绝。

  • 代码分支

可以约定一些规范,来进行分支和版本的管理,比如:
master :主分支,限制分支的push与merge权限;
version-{xxx} :版本分支,从master创建,表示一个版本开发周期,版本结束后删除,打一个版本Tag然后合入主分支;
dev-{xxx} :开发分支,从版本分支创建,用于具体功能开发或bug修复,团队多人合作时的个人临时分支,合并后删除;

  • 代码评审

比较常见的方式是团队内定期组织相关开发人员以会议形式进行code review,如果觉得费时费力,也可以参考开源团队,利用工具在线来进行review。比如说github有pull request,gitlab有merge request,可以在代码合并的节点上进行review,这样的好处是比较开放,也方便留下review记录,以及互相的想法和沟通建议。


参考: 1.https://github.com/xindoo/eng-practices-cn