这是我参与「第四届青训营 」笔记创作活动的的第5天
本文将复习其中两个概念代码质量以及代码评审
代码质量
首先我们先来了解一下好的代码质量具有什么特质?先从以下两段代码进行分析
function runList(array){
var total;
var i;
for(i= O; i<array.length; i++){
total += array[i].price;
}
return total;
}
在阅读上面段代码的时候,可以得知它是遍历一个列表,累加价格,返回总价格
但是我们可能会产生一些疑问
一个什么列表?是什么东西的总价格? 为什么需要计算这个列表的总价格?
function getCartTotal(cartltems){
var cartTotal;
var itemPosition;
for(itemPosition = O; item < cartltems.length; itemPosition++){
cartTotal += cartltems[litemPosition].price;
}
return cartTotal;
}
此处的代码这个代码
具备明确的语义,代码即注释 获取购物车中所有条目的总价格” 阅读代码时,不需要做其他联想 没有泛指,能明确知道变量名,便于调试
可以清晰明白的理解这个函数
那么我们如何提升我们代码的质量呢?
首先提到的是规范,在编程的过程中,同学们或多或少听到过这个词,如命名规范、代码格式、注释规范⋯各种语言的规范也不同,但都有一些相同的道理,此文不展开说明。
其次是稳定的工程结构:目录清晰、模块化、组件化、依赖可控、访问权限⋯
可轻松在代码库中找到示例,重复使用其他人的代码 可以轻松地将新的依赖项添加到其项目,以及迁移到新的依赖项版本 依赖项稳定,并且很少破坏代码
最后是优秀的方案实现:文档、用例、可测性、高内聚低耦合⋯
灵活适度应用不同架构设计思想,譬如:Binder IPC通信、IoC/SPl解耦 可以运用自动化测试手段,保障重构的正确性 更用场景的用例考虑充分,大多数情况下不需要推倒重来
如何评估代码质量呢?
课上着重对圈复杂度这一概念进行了详细的讲解,他对代码质量的评估有不错的作用。
Cyclomatic Complexity,也称条件复杂度,是一种软件度量手段。
计算公式:圈复杂度= num(edges) - num(nodes) + 2
推导公式:圈复杂度=判定条件数+1
例子:
int find(int match){
for(int var in list){
if(var == match! && var!=NAN){
return var;
}
}
}
利用公式:圈复杂度=判定条件数+1=3
U32 find (string match){
for(auto var:list) {
if(var == match && from != INVALID U32)
return INVALID U32;
}
if(session == getName() && key == getKey() {
for (auto& kv: Map){
if (kv.second == last && match == ky.first){
return last;
}
}
}
auto var = Map.find(match);
if(var != Map.end() && (from != var->second)){
return var->second;
}
return INVALID_U32;
];
圈复杂度: 1(for) + 2(if) + 2(if) + 1(for) + 2(if) + 2(if) +1 =11
小结
| 圈复杂度 | 代码状况 | 可测性 | 维护成本 |
|---|---|---|---|
| 1~10 | 清晰 | 高 | 低 |
| 10~20 | 复杂 | 中 | 中 |
| 20~30 | 非常复杂 | 低 | 高 |
| > 30 | 不可读 | 不可测 | 不可测 |
简单分析了两段代码之后,我们可以得出以下一些优质代码的特征
1、小小的代码错误,可酿成巨大的损失
2、优秀的代码可信赖、易维护、Bug少
3、面对庞大的代码需遵循可维护性规则
4、圈复杂度作为度量工具的计算和用途
代码评审
Q1:为什么要做代码评审呢?
通过阅读代码来检查代码是否符合编码规范,前置发现代码质量问题,提升代码可读性、代码正确性、代码安全性。
同时也可以让伙伴之间相互交流、经验传授、学习提升、开放的沟通氛围。
Q2:在代码审查中我们应该关注什么呢?
1、代码规范:
命名:是否定义的清晰准确的变量名、函数名、类名 描述:CR的描述是否准确对应到功能 风格:是否遵循统一的规范 文档:是否同时改动了文档
2、功能设计
设计:是否良好的设计并适用于当前系统 功能:实现是否正确 简洁:实现是否简洁,如果过于复杂是否有更简单的方式 测试:是否包含自动化测试
Q3:代码审查推不动怎么办?
这时候就可以实行我们的小CR规则,把CR代码减少,时间缩短。它可以为我们带来很多好处
1、审查更快,审查者更容易抽多次五分钟时间来审查小型 CL,而不是留出30 分钟来审查一个大型 CL。
2、审查得更彻底,如果是大的变更,审查者和提交者往往会因为大量细节的讨论翻来覆去而感到泪衣,有时甚至到了重要点被遗漏或丢失的程度。
3、不太可能引入错误,由于您进行的变更较少,您和您的审查者可以更轻松有效地推断 CL的影响,并查看是否已引入错误。
4、如果被拒绝,减少浪费的工作,如果您写了一个巨大的 CL,您的评论者说整个 CL的方向都错误了,你就浪费了很多精力和时间。
5、更容易合并,处理大型 CL 需要很长时间,在合并时会出现很多冲突,并且必须经常合并。
6、更容易设计好,打磨一个小变更的设计和代码健康状况比完善一个大变更的所有细节要容易得多。
Q4:如何处理不同意见?
1、不是针对个人 审查的目标是保持代码库和产品的质量。当审查者对您的代码提出批评时,请将其视为在帮助您,而不是对您或您的能力的个人攻击。有时,审查者会感到沮丧并在评论中表达他们的挫折感。对于审查者来说,这不是一个好习惯,但作为开发人员,您应该为此做好准备。问问自己,审查者试图与我沟通的建设性意见是什么?
2、修复代码 如果审查者说他们不了解您的代码中的某些内容,那么您的第一反应应该是澄清代码本身。如果无法澄清代码,请添加代码注释,以解释代码存在的原因。
3、自我反思 当审查者回复对可以改进的事情的评论时,很容易本能地认为评论是错误的,但是,无论您目前多么确定,请花一点时间退一步,考虑审查者是否提供有助于对代码库的有价值的反馈。如果您已经考虑过并且仍然认为自己是正确的,请随时回答一下为什么您的方法对代码库更好。通常,审查者实际上是在提供建议,他们希望您自己思考什么是最好的。所以提供并告诉他们更多的上下文。
4、解决冲突 解决冲突的第一步应该是尝试与审查者达成共识。如果您无法达成共识,基于技术事实和业界标准规范进行衡量。
小结
1、CR能前置地发现代码质量问题。
2、将CR做得小点能加快评审效率。
3、谦逊坦诚面对不同的评审意见。
总结
但是很多人开始实践的过程中我们可能会很痛,没做几天就放弃了。但是那一次成长不是痛苦的,我们要在过程中理解圈复杂度和代码质量的重要性、让代码评审能够前置的发现代码问题。都说14天一个习惯,不妨在坚持坚持,最后祝愿大家都能养成一个良好的习惯!
参考文章
萌新初学,本文为笔记,大佬若有更好的方案欢迎评论区留言