圈复杂度计算方法其实很简单。这事复杂在它涉及到代码逻辑的复杂性,但通过一个公式就能得出结果。
先说最重要的,圈复杂度(Cyclomatic Complexity)的计算公式是:M = E - N + 2P,其中 M 是圈复杂度,E 是边数,N 是节点数,P 是连通分量数。举个例子,去年我们跑的那个项目,大概有 3000 行代码,通过这个公式计算,得出的圈复杂度是 20。
我一开始也以为这个指标很难理解,但后来发现不对,其实它就是衡量代码中分支和循环的数量。比如,一个简单的函数,如果只有 if-else 结构,那么它的圈复杂度就是 2。
还有个细节挺关键的,就是连通分量。这个指的是代码中独立的部分,如果代码中有多个独立的功能块,那么每个功能块都是一个连通分量。
等等,还有个事,虽然圈复杂度可以量化代码的复杂度,但它并不能完全代表代码的质量。一个高圈复杂度的代码可能结构混乱,而一个低圈复杂度的代码可能结构清晰。
所以,我的建议是,在评估代码复杂度时,除了看圈复杂度,还要结合代码的可读性、可维护性等因素综合考虑。你觉得呢?
2023年,我在一个技术论坛上看到一个帖子,有人问如何计算圈复杂度。我那时候刚好在整理自己的项目文档,就顺口回了一句:“,这不简单,就是用环路计数法啊。”
当时我正在北京的家中,手头翻着那本尘封已久的《软件工程》,里面有一段详细的解释。我记得那本书里写着,圈复杂度(Cyclomatic Complexity)是衡量程序复杂性的一个指标,它是通过Erdős图来计算的。我随手在草稿纸上画了个图,解释道:“比如,你有一个程序,里面有一百行代码,十个循环,五个分支,那你的圈复杂度就是一百减去十再减去五个,再除以二,结果是45。”
突然,我想起了自己大学时的一次编程比赛。那时候我们团队为了提高代码的圈复杂度,故意在程序里加入了很多冗余的逻辑,结果那个程序真的运行得很慢。现在想想,那大概是我们第一次接触到圈复杂度这个概念,但当时并不懂得如何正确地应用它。
说起来,我还记得有一次在公司的技术评审会上,我们因为一个模块的圈复杂度过高而争论了很久。那个模块的复杂度达到了80,我们讨论了好几个回合,最后还是决定重构它。
等等,还有个事,我突然想到。我曾经在书上看到一个例子,说一个优秀的程序员,他的代码圈复杂度一般不会超过10。这个数字听起来很神奇,但我也不知道这是真的还是假的。