认知复杂度——估算项目代码的理解成本


作者: Arnold

1. 摘要

Cognitive Complexity:认知复杂度,是由sonarQube设计的一个算法,算法将一段程序代码被理解的复杂程度,估算成一个整数——可以等同于代码的理解成本。
IntellliJ IDEA支持sonar插件,可以实时计算函数的认知复杂度,当复杂度过高时将提醒重构。

认知复杂度的计算基于以下三规则:语法糖不增加理解难度、打断线性代码执行增加理解难度、多层嵌套增加理解难度。

2. 历史背景

(此部分可略过)

2.1 工程复杂度背景

最初工业界普遍使用圈复杂度(Cyclomatic Complexity)来描述一段代码逻辑的“可测性与可维护性”,尽管用它来描述“可测性”很好(可测性的意思是:需要构建出完美的单元测试需要多少代价),但这种模型不能很好的描述代码的“可维护性”。
认知复杂度很好的弥补了“圈复杂度”的这个缺点,用一种全新的、简单的度量方法,准确地反映代码的理解成本,以及维护的难度。
“认知复杂度”与编程语言无关,它可以用来测量文件、类、过程与函数等等概念下的复杂度。

2.2 有哪些问题待解决

  • Thomas J. McCabe设计的圈复杂度是一个业界标准,最初目的是用来识别“难以测试和维护的软件模块”——但是用这种算法只能算出一个模块最少的全覆盖测试用例数量,而不能算出一个精确的模块“理解难度”。因此圈复杂度一样的两段代码,维护难度却有可能天差地别,用圈复杂度来理解维护难度,导致我们对模块代码有错误估计。
  • 圈复杂度的理论是在1976年于Fortran语言环境下设计的,如今使用它来衡量新语言不再是那么全面了。一些现代的语言结构,如try-catch与lambda没有被考虑在内。
  • 每个方法都的最小圈复杂度都是1,导致了“圈复杂度”与其方法数量是相关。一个很好理解的Class(类),也可能因为包含多个简单方法,总复杂度被抬得很高。
    为了解决这些问题,SonarQube制定了认知复杂度(Cognitive Complexity),一方面解决了圈复杂度在现代语言结构的不足,一方面使复杂度在方法、类、应用程序级别都有实际意义。 更重要的是,这个复杂度值与程序员理解这些代码片段所需的直觉(理解难度)相对应。

2.3 一个例子

这里给出一个很有用的例子,可以指出圈复杂度的问题。以下两段方法有着相同的圈复杂度,但是在理解难度上差非常多:
image.png
圈复杂度理论,对上图的两个方法给出等同的复杂度,然而从直觉上显然左边的sumOfPrimes要更难以理解一些。这也是为什么认知复杂度舍弃了使用数学模型来评估一段逻辑,改用一组简单的规则,把代码的直觉理解程度转为一个数字表达。

3. 认知复杂度解释

3.1 基本原则

&#x

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值