CodeReview主要Review什么? 什么是CodeReview? CodeReview,意即代码审查,是指一种有意识和系统的召集其他程序员来检查彼此的代码是否有错误的地方。 通常进行CodeReview会有以下效果:提高代码质量和可维护性,可读性等。查漏补缺,发现一些潜在的问题点等。最佳实践,能够更好更快的完成任务的方法。知识分享,Review他人代码时,其实也是一个学习的过程,自己也会反思总结。 为什么要CodeReview? 要不要CodeReview,需要结合当前的环境和形势来决定。如果项目组开发任务极其紧张,此时再进行CodeReview可能会收到不利的效果。因势利导,求同存异是CodeReview的核心所在。 CodeReview尤其需要和项目组成员沟通和配合,同时也在检验各成员的技术水平。 尤其需要注意的是,人都有惰性,每个人都有自己的一套行为准则和规范,要想把他们的行为或规范统一起来,很容易使他们产生抗拒心理。 在CodeReview之前,和项目成员沟通好,有一个共同的愿景,并辅助以相应的培训,把部分人员的短板补齐。会减轻项目成员的一些不适感,也会使得项目运行更加顺畅。 同时,也要注意,不要事事求完美主义,一步求成。要知道慢即是快。 CodeReview的前提条件 CodeReview本身属于事后工作,可以起到查漏补缺的作用。 在推行CodeReview时,需要先提前准备以下几个工作,以便团队能够更快更好的接受和实施。建立规范,包含:编码规范,如变量命名,文件命名规范等设计原则,如单一职责原则,最少知识原则等分支管理策略完善的文档,方便查阅。文档内容最好能共建,千万不可出现一言堂制定CodeReview流程目标,以及实施周期。 例如,当前我所带的项目组,根据困难程度,CodeReview实施分为3个阶段。第一阶段,重点关注,恰到好处的函数注释,硬编码问题,常见变量命名规则等,预期实施周期为13个月第二阶段,重点关注,代码耦合性,单一职责、最少知识原则,潜在隐患,性能问题等,预期实施周期为36个月第三阶段,重点关注,模块实现方案,设计模式,最佳实践,代码重构等。 在实施过程中,如果遇到比较大的阻力或困难,推行CodeReview所得到的收益较低时,可以考虑适当休息一段时间。 CodeReview如何实施? 从当前项目的实施过程的体会,以及结合其他人的一些经验来看,在CodeReview时建议:单次查看代码不多于500行,人的精力有限,一次审查太多的代码,收益可能不理想。单次审查建议不要超过30分钟常见的CodeReview项 git提交规范 gitcommit提交规范,如:不标注信息不及时commit提交时标注的信息不规范等 都是严重阻扰review的因素之一,除了常规的描述信息外,还可以按类型等备注:feat:新特性fix:修改问题refactor:代码重构docs:文档修改chore:其他修改test:测试用例修改style:代码格式修改等等 当然,也要以利用一些工具,来协助我们完成基本的约束和检查。如:优雅的使用Git风格 1。可读性 衡量可读性,有很好的实践标准,即CodeReview时能否非常容易的理解代码逻辑,如果不能,那意味着代码的可读性要进行改进。 2。命名命名对可读性非常重要,我个人倾向于函数名类名长一点都没关系,但必须能清晰的表明函数类的作用。英语用词尽量准确,哪怕需要借助翻译工具,也是值得的。但有一点需要注意,如果使用的单词很冷门,都没人认识,那就不要使用。 3。函数体长度类长度函数体太长,不好阅读,一般建议不要超过50行类太长,如超过10000行,那可能就要看下是否违反了单一职责原则。 4。参数个数 不要太多,一般不要超过5个,超过5个,建议使用对象 5。注释 恰到好处的注释,能够帮助我们理解函数类的作用。架构设计 1。单一职责原则 这是经常被违背的原则,也是最难运用好的原则。一个类只做一类相关的事情一个函数方法,最好只做一件事情 2。行为是否统一 1)什么是行为统一?例如:错误处理是否统一错误提示是否统一弹出框是否统一。。。 2)同一逻辑行为,有没有执行同样的代码路径 低质量的代码一个特征是,同一逻辑行为,在不同的地方或不同的方式触发时,没有执行同样的代码路径(产生出不同的结果),或者是各处copy一份实现,导致非常难以维护。 3。代码污染 代码有没有对其他模块强耦合 4。重复代码 主要看有没有把公用组件,可复用的代码、函数抽取出来 5。开放封闭原则 简单理解是,看代码好不好扩展 6。健壮性核心数据有没有强制校验?对业务有没有考虑完整,逻辑是否健壮有没有潜在的bug?有没有内存泄露?有没有循环依赖? 7。错误处理 有没有很好的ErrorHandling?如网络出错,IO出错等。 8。面向接口编程面向对象接口编程 主要看有没有进行合适的抽象,把一些行为抽象为接口 9。效率性能客户端程序对频繁的消息和较大数据等耗时操作是否处理得当关键算法的时间复杂度是多少?有没有潜在的性能瓶颈? 10。代码重构新的改动是打补丁,让代码质量继续恶化,还是对代码质量提升有帮助?低质量代码的常见特征违反单一职责原则同一逻辑行为,通过不同的方式触发时,不会执行同样的代码路径缺少注释函数类命名乱,词不达意,或挂羊头卖狗肉,例如exportfunctionsetDefaultImg(res){letimgUrlgetImagePrefixUrl()letpreviewImgSrcrequire(assertsimagesicon。png)if(res。imgId){previewImgSrc{imgUrl}{res。imgId}。{res。type}?t{newDate()}}returnpreviewImgSrc}复制代码 上例函数,其实是想对传入的参数进行判断,如果值无效,取默认图片,否则返回拼接地址好的imgsrc相对地址。从函数的实现来看,有如下几个问题:函数名setDefaultImg并不合适,无任何对数据的更新修改,最终目的是想拿到img的拼接地址(或者默认图片)形参res是一个对象,实际使用到的属性只有两个基本类型,遵循最少知识原则,应修改形参。letimgUrl,其实是拼接url的前缀,取名如imgPrefixUrl会比较合适。let使用不当,如letimgUrl,因涉及不到变量再赋值,使用const是比较合适的res。imgId,即异常情况的处理,少了对res。type的处理变量命名,如previewImgSrc,取此名也不太合适,该src使用的目的并不确定,建议使用有比较通用涵义的名字。 可考虑重构为:exportfunctiongetImgSrc(imgId,imgType){if(typeofimgId!stringtypeofimgType!string){returnrequire(assertsimagesicon。png)}return{getImagePrefixUrl()}{imgId}。{imgType}?t{newDate()}} 作者:JamesZhang80078 链接:https:juejin。cnpost6844904009065578510 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。