圈复杂度是什么?
大家好,我是晨光。最近帮同事 CodeReview 了一个项目,让我回想起了https://t.zsxq.com/185tSSm6x之前分享过的这个贴。里面提到的代码规范,我日常 Coding 时用到的频率也很高。今天想和大家分享的是代码规范以及圈复杂度的治理。
1、代码规范
注释规范,写代码一定要写好注释啊,特别是复杂的方法,或者一些在你实现功能的时候就比较难以理解的逻辑,一定要加上注释,最好还可以备注上需求 prd 链接等等,让代码变得有迹可循。
命名规范,没什么好说的,常见的就驼峰命名,还有语义化命名。
还有通用逻辑尽可能抽离;方法传参个数尽量精简;用 TS 写的代码少用 any,尽量都能够标注出类型;等等还有很多。
未做完的功能点,记得打上 //TODO,防止忘记。
2、圈复杂度
「圈复杂度是一种用于衡量代码复杂性的软件度量指标。它通过计算代码中的决策点数量来估算代码的复杂性和可测试性。决策点包括条件语句(如 if、switch)、循环语句(如 for、while)以及逻辑运算符(如 &&、||)等。」
说白了就是一个方法内,条件越多,代码就越复杂,为了我们能够更快的读懂代码,代码越简单读起来越快,理解起来更容易,可以添加圈复杂度限制。
我们在 RN 和 NodeJS 中,可以使用 eslint 提供的 eslint-plugin-complexity 来设置整个项目的圈复杂度。
先安装,再在 .eslintrc.js 文件中加上如下配置

圈复杂度的计算方法是通过构建控制流图(Control Flow Graph)来实现的。控制流图是用来表示代码中的控制流程的有向图,每个节点代表一个基本块(Basic Block),每个边代表控制流的转移。
20 可以调整,你希望一个方法最多有多少个决策点就调整为多少。
圈复杂度的计算公式为:圈复杂度 = 决策点数量 + 1。决策点数量指的是控制流图中的分支节点数量,即 if 语句、switch 语句、循环语句等。
降低圈复杂度可以提高代码的可读性、可维护性和可测试性,看看有哪些方法
3、降低圈复杂度的方法
- 拆分:将复杂的函数或方法拆分成多个小的、可重用的函数或方法,每个函数或方法只负责一个明确的任务。
- 减少条件语句嵌套:尽量避免过多的条件语句嵌套,可以使用早返回(early return)或者提前判断的方式来减少嵌套。
- 使用多态性和继承:通过使用面向对象编程的概念,可以使用多态性和继承来减少条件语句的使用,提高代码的可扩展性和可维护性。
- 提取公共逻辑:如果多个条件语句中存在相同的逻辑,可以将这部分逻辑提取出来,减少重复代码,提高代码的可读性和可维护性。
通常情况下,我们只能严格要求自己,把代码写的漂漂亮亮,该拆分拆分,该提取提取,但也只能要求自己。而规则可以要求所有人,不管到底能约束多少,但至少比毫无约束强一些。
近期除了做 CodeReview,还做了代码复杂度治理的技改。人与人的思维存在差异,这点从代码逻辑上就能体现,拆了一个 40 多个复杂度的方法,for 套 for,套 if,再套 for,一个方法几百行也没拆分,假设不做限制,真的没第二个人敢改这坨代码。
还有一些情况是 if 条件的判断条件是否合理,多个 if 是否可以合并,或者是 if 判断的某个变量赋值是否可以简化等等,代码不是写完就完事儿,方便维护才是好代码!
对于 if 以及 ?. 这种用法的圈复杂度的计算方法如下:
- if 语句:每个 if 语句都算作一个决策点。
- ?.(可选链操作符):可选链操作符用于处理可能为 null 或 undefined 的属性或方法调用,它不会增加圈复杂度。
一开始以为 ?. 会算复杂度,问了 GPT 它说不会。我在圈复杂度治理的过程中也确实验证了这一点,确实不会。

4、总结
- 日常开发时尽量遵循一套合理的代码规范,保持代码风格统一
- 尽量保证代码的圈复杂度尽可能的低,提高可读性和可维护性
- 能拆分拆分,能提取提取,保持代码精简
保持良好的代码习惯,方便自己也方便他人😭
以上,全文完,有收获记得点个赞呀👍~
