# CodeReview规范

## 目标和原则

- 提高代码质量，及早发现潜在缺陷，降低修改/弥补缺陷的成本
- 促进团队内部知识共享，提高团队整体水平
- 评审过程对于评审人员来说，也是一种思路重构的过程，帮助更多的人理解系统
- 是一个传递知识的手段，可以让其它并不熟悉代码的人知道作者的意图和想法，从而可以在以后轻松维护代码
- 可以被用来确认自己的设计和实现是一个清楚和简单的
- 鼓励相互学习对方的长处和优点
- 高效迅速完成Code Review

## 流程和规则

采用[Git Flow](http://blog.jobbole.com/76867/) + [Pull Request（PR）](http://blog.jobbole.com/76854/)模式来做Code Review。

### Git Flow



![img](https:////upload-images.jianshu.io/upload_images/1586287-c4990c0f5377a868.png!thumbnail?imageMogr2/auto-orient/strip%7CimageView2/2/w/614/format/webp)

图片

### Pull Request（PR）



![img](https:////upload-images.jianshu.io/upload_images/1586287-d0b7c119556e472e.png!thumbnail?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp)





![img](https:////upload-images.jianshu.io/upload_images/1586287-1596c530de8ffe62.png!thumbnail?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp)



#### **Pull Request 的说明**

- 任务完成才能提交PR
- 严禁一个PR里面有多个任务，除非它们是紧密关联的
- PR提交之后只允许针对Review发现问题再次提交代码，除非有充足的理由，严禁在同一个PR中再次提交其它任务的代码
- 提交PR时候有一个描述框，内容会自动根据Commit的message合并而成。切记，如果一次提交的内容包含很多Commit，请不要使用自动生成的描述。请用简短但是足够说明问题的语言（理想是控制在3句话之内）来描述： 你改动了什么，解决了什么问题，需要代码审查的人留意那些影响比较大的改动。特别需要留意，如果对基础、公共的组件进行了改动，一定要另起一行特别说明。
- PR应该在1~2个工作日内被合并或者被拒绝
- **发起Pull Request以后，请将Pull Request的链接通过Email发给代码评审者，以此通知对方及时进行审核。(BUG修复类当日必须完成合并或者拒绝，功能类或者觉得有重大调整需要会议Review必须在邮件中明确时间和会议人员)**



## **Checklist**

Code Review主要检查代码中是否存在代码的一致性、编码风格、代码的安全问题、代码冗余、是否正确设计以满足需求（功能、性能）等等。

#### 完整性检查

- 代码是否完全实现了设计文档中提出的功能需求
- 代码是否已按照设计文档进行了集成和Debug
- 代码是否已创建了需要的数据库，包括正确的初始化数据
- 代码中是否存在任何没有定义或没有引用到的变量、常数或数据类型

#### 一致性检查

- 代码的逻辑是否符合设计文档
- 代码中使用的格式、符号、结构等风格是否保持一致

#### 正确性检查

- 代码是否符合制定的标准
- 所有的变量都被正确定义和使用
- 所有的注释都是准确的
- 所有的程序调用都使用了正确的参数个数

#### 可修改性检查

- 代码涉及到的常量是否易于修改(如使用配置、定义为类常量、使用专门的常量类等)
- 代码中是否包含了交叉说明或数据字典，以描述程序是如何对变量和常量进行访问的
- 代码是否只有一个出口和一个入口（严重的异常处理除外）

#### 可预测性检查

- 代码所用的开发语言是否具有定义良好的语法和语义
- 是否代码避免了依赖于开发语言缺省提供的功能
- 代码是否无意中陷入了死循环
- 代码是否是否避免了无穷递归

#### 健壮性检查

- 异常处理和清理（释放）资源
- 代码是否采取措施避免运行时错误（如数组边界溢出、被零除、值越界、堆栈溢出等）

#### 结构性检查

- 程序的每个功能是否都作为一个可辩识的代码块存在
- 循环是否只有一个入口

#### 可追溯性检查

- 代码是否对每个程序进行了唯一标识
- 是否有一个交叉引用的框架可以用来在代码和开发文档之间相互对应
- 代码是否包括一个修订历史记录，记录中对代码的修改和原因都有记录
- 是否所有的安全功能都有标识

#### 可理解性检查

- 注释是否足够清晰的描述每个子程序
- 是否使用到不明确或不必要的复杂代码，它们是否被清楚的注释
- 使用一些统一的格式化技巧（如缩进、空白等）用来增强代码的清晰度
- 是否在定义命名规则时采用了便于记忆，反映类型等方法
- 每个变量都定义了合法的取值范围
- 代码中的算法是否符合开发文档中描述的数学模型

#### 可验证性检查

- 代码中的实现技术是否便于测试

#### 可重用性

- DRY（Do not Repeat Yourself）原则：同一代码不应该重复两次以上
- 考虑可重用的服务，功能和组件
- 考虑通用函数和类

#### 可扩展性

轻松添加功能，对现有代码进行最小的更改。一个组件可以被更好的组件替换

#### 安全性

进行身份验证，授权，输入数据验证，避免诸如SQL注入和跨站脚本（XSS）等安全威胁 ，加密敏感数据（密码，信用卡信息等）

#### 性能

- 使用合适的数据类型，例如StringBuilder，通用集合类
- 懒加载，异步和并行处理
- 缓存和会话/应用程序数据

>  **代码检查包括不局限于上述清单，提交人应在本地自我完成代码格式、架构设计、面向对象分析与设计等检查。**



## Execution

### 准备阶段

1. **评审规范和标准**

   在CR前设计确定评审规范和标准是必要，通过规范和标准我们在审查过程中可以有据可依，有理可循，而且还可以做到标准统一。

2. **选择CR活动的参与者**

   在CR开始前，必须把本次CR活动的对象、审查内容以及审查的规范和标准通过email通报给所有的参与者。

3. **选择CR活动的实施方式**

   CR活动有很多形式可供我们选择，我们可以根据实际情况选择桌面式CR、演示讲解式CR、一对一的座位CR等等。(**一般按新增功能桌面式CR、里程碑功能演示讲解式CR、BUG修复一对一的座位CR**)

   

### 实施阶段

充分的事前准备，只是做好CR活动的前提，在CR实施过程中，我们要做好以下工作。

1. **准确记录**

   对于CR过程发现的问题，我们必须清晰准确的记录，可以使用问题点记录单，明确记录的项目和内容。

2. **讲解与提问**

   CR过程中，要采用代码作者讲解和审查者提问方式。审查者不能只在发现问题时提问，同时也要根据本次审查的内容要求代码作者对某个特定问题的讲解。

3. **逐项审查**

   对事前确定的审查内容，要逐项审查，不能因为时间不足等因素一扫而过。

4. **注意气氛**

   实施审查时，要营造一个讨论问题、解决问题的氛围，不能把审查会搞成批判会，这样会影响相关人员的积极性。

   

### 事后跟踪

确认发现的问题 CR结束后，对发现的问题，首先需要确定以下内容。

1. 问题点的难易程度以及影响的范围；

2. 解决问题的责任者和问题点修正结果的确认者；

3. 解决问题点的时限；

4. 修正问题责任者 对于修正问题责任者，在问题点的修正过程中，要三方面内容的记录（问题点的原因；解决问题点的对策；修正的内容。）；

5. 修正结果确认者做为修正结果的确认者，必须按照事前约定的时限及时的对修正结果进行全面的确认。

   

## Skills

1. 目标明确，No magic；
2. 覆盖度比深度重要，覆盖度追求100%；
3. 频率比仪式感重要，坐公交蹲厕所打开手机都可以 Review 别人代码，不需要专门组织会议；
4. 粒度要尽可能小，一个组件一个方法均可，可以结合 Git Flow；
5. 24H 内处理，无问题直接 merge，有问题一定要留 comment，并且提供 action；
6. 对于亟待上线来不及 Review 的代码，可以先合并上线，上线后再补充 Review；
7. 需要自上而下的推动，具有完善的规范，同时定期总结 Review 经验来丰富开发规范；
8. 保持积极的正面的态度，作者要能够虚心接受别人的建议；评审者需要积极的正面的向作者提意见，合力而行；
9. 让不同的人（不超过3个）Review你的代码，从不同的方向评审代码，培养B角，还能增加团队凝聚力；
10. 不要太正式，忘掉Checklist，花几分钟进行交流，在相互信任中通过讨论得到了有意义和有建设性的建议和意见；
11. CR 并不只是为了找错，看到好的代码，不要吝啬你的赞美；
12. 学会享受Code Review，鼓励开发者间更多的沟通，互相学习，营造技术文化氛围，这样团队和个人都会自动进化。



## 附录

### 演示讲解式CR Steps

1. 作者和评审者坐在一起，由作者讲解自己负责的代码和相关逻辑；
2. 评审者在此过程中可以随时提出自己的疑问，同时积极发现隐藏的bug，对这些bug记录在案。
3. 代码讲解完毕后，评审者给自己安排几个小时再对代码审核一遍。
4. 评审者根据审核的结果编写“代码审核报告”，“审核报告”中记录发现的问题及修改建议，然后把“审核报告”发送给相关人员。
5. 作者根据“代码审核报告”给出的修改意见，修改好代码，有不清楚的地方可积极向代码评审者提出。
6. 作者 bug fix完毕之后给出反馈。
7. 评审者把Code Review中发现的有价值的问题更新到"代码审核规范"的文档中，对于特别值得提醒的问题可群发email给所有技术人员。

> “代码审核规范”文档：记录代码应该遵循的标准。 代码评审者根据这些标准来Code Review代码，同时在Code Review过程中不断完善该文档。

