2020-12-25

博客园Logo
首页
新闻
博问
专区
闪存
班级

代码改变世界
搜索
注册
登录
返回主页
机长梦话
不会拍电影的程序员不是好机长
联系
订阅
管理
如何做好Code Review

Code Review(代码审查)很多团队都会做,效果如何不好说。如果你能轻易地从一堆出自正经团队之手的代码里找出几个低级错误,往往意味着团队管理者长期忽视了Code Review的重要性。

根据经验,匆匆应付功能实现和漏洞修复而将Code Review流于形式的团队不在少数。当然,每个人都能列举一大堆“客观原因”,而且每一条理由听起来都是那么的有说服力。然而,没做好就是没做好,狡辩只会让场面变得更加恶心。

What(什么是Code Review)
A code review is the process of examining written code with the purpose of highlighting mistakes in order to learn from them.
– Techopedia
这是目前我见过对Code Review最言简意赅的定义。其实怎么描述并不重要,重要的是我们要达到什么样的目的。

Why(为什么要做Code Review)
提高代码质量是程序员端稳饭碗、少挨点儿骂的最有效途径。其实Code Review就是很好的相互切磋、共同进步的机会,效果要比独自埋头干啃《21天精通×××》之类的“宝典”好得多。当然,前提是目的明确、态度端正。

Code Review主要目的就两个:

查错

Code Review不是用来查找低级错误的,而是参与者以提交者以外的视角阅读和审视代码,尽可能地找到逻辑上的问题。

学习

与其说Code Review重在找到问题,不如说其核心目的在于营造团队学习氛围、提升成员对软件品质的追求。我经历过不少团队,为了营造学习氛围,生拉硬拽地要求成员定期举行技术分享会,结果往往敷衍了事、不了了之。

How(怎样做Code Review)
下面根据Code Review中涉及的主要人物角色来讲讲我推荐的方式。注意,这不是标准答案。

具体划分角色责任之前,我建议每个技术团队都要找到并严格执行适合本团队技术栈的编码规范,甚至包括IDE配置和开发环境参数设定等,以确保每位成员都“说着同样的语言”,并减少在命名规则、排版样式等方面的争论,将时间和精力聚焦到对功能实现和业务优化这些实质性的问题上来。

开发小组技术负责人

每一位开发小组技术负责人都应该积极实施并维护Code Review机制,要求每位成员在提交代码的时候,都必须经过交叉Review,也就是每一次代码提交到主干时,都必须经过另一位相同技术领域同事的Review,否则将被视为提交了与存在编译时错误的代码同等的严重过失。

每次代码提交的交叉Review,开发小组技术负责人应当随机抽取包括自己在内的任何一位技术人员进行,不要让提交者能够很轻易地预知将会是谁来做自己这一次的Reviewer,否则很容易变成形式主义。

并且,对于Feature实现的Code Review,开发小组技术负责人应该较为频繁但不定期地进行公开Review。组织一场会议,召集整个开发小组的成员一起对此次提交的代码进行审查。

提交者

不论Code Review是私下的还是公开的,提交者都不能提交任何存在编译时错误的代码,这是非常低级的错误。首先在提交代码之前再次进行编译,是确保即将提交的代码不存在编译时错误的必要步骤。其次,也是很多人容易疏忽的,确保本次新增的本地资源文件都被加入了源代码管理,否则即使本地能编译通过,别人拿到你的代码也依然存在编译时问题。

提交代码之前,自己先diff一下,首先确保代码不存在前面提到的诸如命名、格式等方面的低级错误;然后确定自己对每一处代码变动的理解都非常明确,并且自己已经找不出改进方案;最后确保所有Hard Code都已经被移除,这一点可以参考我之前写的《没什么技术含量的Remove Before Flight》。

提交者在代码被Review之前,还应该调整好心态,把别人的询问、质疑、建议、批评,通通视作可能的提升机会,而不要主观上认定自己给出的就是最优解,而别人都是“不明真相的围观群众”。也许别人在不了解背景信息或上下文的情况下,给出了错误的建议,提交者也应当将此作为锻炼思维和口才的友好辩论,而不是玻璃心受到了侵犯似的直接怼回去。

参与者

参与者应该对编码规范了然于心,对于代码中每一处不符合团队现行编码规范的地方都要不厌其烦地标注出来。很多人认为这个无所谓,反正机器最后读的都是0和1——对,机器只认识0和1,所以源代码其实是写给人看的。不管代码由多少人写就,最终看上去如同出自同一人之手,这种代码的阅读体验和效率绝对要比那种百家争鸣式的好得多。

如果是面向对象的编程语言,参与者应当考察提交者对抽象的理解和实践,是否准确以及是否过浅或过深。抽象过浅,看上去往往是大杂烩;抽象过深,读起来显得吃力。对于这两种情况,参与者都可以提出自己的看法和建议,不要抱着“你这不行,听我的”的态度,否则很容易形成对立的情绪,进而影响团队对Code Review的积极性。

对于代码实现是否存在改进空间这个问题,参与者应该在阅读新代码时,尽可能全面地去理解问题域、了解需求的具体细节,而不是想当然地抛出质疑和意见,给人以浮躁的印象。如果参与者确定自己清楚地理解了需求和问题,依然对当前的代码实现有改进建议,那么就大胆地提出来,这就是Code Review的核心目的!

转载请注明出处。版权所有©1983-2018 麦机长,保留所有权利。
分类: 技术杂文
好文要顶 关注我 收藏该文
麦机长
关注 - 0
粉丝 - 330
推荐博客
+加关注
0 0
« 上一篇: Dart单例模式最佳实践
posted @ 2020-12-24 22:05 麦机长 阅读(106) 评论(0) 编辑 收藏
刷新评论刷新页面返回顶部
登录后才能发表评论,立即 登录 或 注册, 访问 网站首页
写给园友们的一封求助信
【推荐】News: 大型组态、工控、仿真、CADGIS 50万行VC++源码免费下载
【推荐】有你助力,更好为你——博客园用户消费观调查,附带小惊喜!
【推荐】博客园x丝芙兰-圣诞特别活动:圣诞选礼,美力送递
【推荐】了不起的开发者,挡不住的华为,园子里的品牌专区
【福利】AWS携手博客园为开发者送免费套餐+50元京东E卡
【推荐】未知数的距离,毫秒间的传递,声网与你实时互动
【推荐】新一代 NoSQL 数据库,Aerospike专区新鲜入驻

相关博文:
· codereview应该怎么做
· 如何在团队中做好CodeReview
· reviewvue.js官方文档
· VCXPorschePIWISIIIReview
· VCXPorschePIWISIIIReview
» 更多推荐…

最新 IT 新闻:
· 游族CEO林奇被搭档投毒,三体宇宙会崩塌吗?
· 被在线教育公司盯上的“SA圈”:陪你学习,还是卖货给你?
· 出货量破亿!联发科第一次登顶智能手机SoC
· AirPods Max音质有短板!这是硬伤
· Office Word又添新功能“微软编辑器”:检查并修正语法错误
» 更多新闻…
公告
MVP (Visual C#)
昵称: 麦机长
园龄: 13年4个月
荣誉: 推荐博客
粉丝: 330
关注: 0
+加关注
随笔分类 (85)
.NET程序员技术面试迷你手册(C#版)(5)
Autumoon Code Library(1)
C# 3.0 探索之旅(9)
Flutter/Dart(2)
LINQ 探索之旅(5)
Office Live for Small Business(4)
Ruby(2)
白话C#系列(8)
读书笔记(3)
多普达 Touch Diamond 创新前沿体验(4)
公告(2)
技术杂文(8)
简明设计模式——C#版(25)
时间管理(7)
友情链接
时间管理小组@豆瓣
时间管理小站
最新评论

  1. Re:mixin很难吗?
    对于幸福,笑星范伟有过这样一段精彩的道白:“幸福就是饥饿时,看见别人手里拿着包子,他就比我幸福;寒冷里,看见别人穿着棉袄,他就比我幸福;悲伤中,看见别人在微笑,他就比我幸福!”这几句简单的幽默,是否可…
    –前方一片光明
  2. Re:Dart单例模式最佳实践
    高度的判断不在于视野,而在于心态;距离的判断不在于长度,而在于行动!【暖心良言】
    –前方一片光明
  3. Re:以人为鉴,可以明得失——《程序员职场第一课》书评
    感谢前辈的文字,受益匪浅
    –AZHAOJIAN
  4. Re:面试那点事儿

    –世凡
  5. Re:面试那点事儿
    不错,对于面试我和你的观点想似,不过我没有你的文采和MVP.
    –郑隆2015
    阅读排行榜
  6. 多线程(61743)
  7. 值类型和引用类型的区别(49664)
  8. 面向对象主要概念(12710)
  9. 没什么技术含量的Remove Before Flight(9778)
  10. 反射(6138)
    评论排行榜
  11. 多线程(53)
  12. Touch Diamond Remote —— 世界就在指尖(39)
  13. 值类型和引用类型的区别(35)
  14. 面试那点事儿(31)
  15. 面向对象主要概念(30)
    Copyright © 2020 麦机长
    Powered by .NET 5.0.1-servicing.20575.16 on Kubernetes
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
func (c *cAsset) CreatComponent(r *ghttp.Request) { var req *v1.CreateComponentReq if err := r.Parse(&req); err != nil { r.Response.WriteJson(g.Map{ "code": 1, "msg": err.Error(), }) } createRequest := &creativecomponent.CreateRequest{ AdvertiserID: req.AdvertiserID, } res, err := service.Asset().Create(createRequest) if err != nil { r.Response.WriteJson(g.Map{ "code": 2, "msg": err.Error(), }) } r.Response.WriteJson(res) }这段代码中creativecomponent.CreateRequest的过滤条件为type CreateRequest struct { // AdvertiserID 广告主ID AdvertiserID uint64 `json:"advertiser_id,omitempty"` // ComponentInfo 组件信息 ComponentInfo *ComponentInfo `json:"component_info,omitempty"` },其中ComponentInfo为type ComponentInfo struct { // ComponentID 组件ID ComponentID model.Uint64 `json:"component_id,omitempty"` // ComponentType 组件类型 ComponentType enum.ComponentType `json:"component_type,omitempty"` // ComponentName 组件名称。长度小于等于20。一个中文长度为2 ComponentName string `json:"component_name,omitempty"` // ComponentData 组件详细信息。不同的component_type对应的值不同,具体的结构见创建或更新接口定义 ComponentData ComponentData `json:"component_data,omitempty"` // CreateTime 创建时间。格式"2020-12-25 15:12:08" CreateTime string `json:"create_time,omitempty"` // Status 组件审核状态。 Status enum.ComponentStatus `json:"status,omitempty"` }想要把ComponentInfo作为参数放到createRequest中,该怎么?请详一点
07-20

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值