最近看了一份代码,我看的有点眩晕。想起来意大利面,意大利面个人还是蛮喜欢的。可是面对一份意面风格的代码,我就有点想吐了~
意面代码
意大利面,想必很多人都吃过。比较常见的长这样:
老外对糟糕的代码,有种有趣的叫法:Spaghetti code,意思就是意大利面条式代码。代码像面条一样混乱的堆成一团,很难理清头绪。
要确切地界定什么样的代码是意大利面条式代码,这好像无法准确的做一个定义。只能用栗子来描述,大体上什么样的代码可以称为意面式代码:
深度的条件嵌套风格,比如if条件嵌套很多层,switch 嵌套switch....
很多GOTO语句,当然这可能不常见,但是比如在Linux内核驱动的时候,你会看到很多栗子。但一般都是异常后在函数体内跳转。
混乱的return处理,比如多点return,这很容易导致bug。
滥用异常exception处理,甚至异常也嵌套
在面向对象编程中,设计混乱的类,或者非常长的类。有的代码,使用的是C++语言,可是写出来的代码却完全是面向过程式风格,当然这里想说的不是语言,而是编程思维,即便C语言也可以写出面向对象的赶脚。
**圈复杂度(Cyclomatic Complexity)**很高的代码
函数写的非常长
全局变量满天飞,导致代码逻辑混乱,无法维护
条件语句内,过于复杂且条理不清的逻辑判断,一个if语句,整了一推语句与或非.....
混乱的多线程同步、通信处理
.......
何为圈复杂度
圈复杂度(Cyclomatic Complexity),这个有可能很多朋友不知道。来简单描述一下什么是圈复杂度。
圈复杂度是由 Thomas McCabe 开发的一种用于确定程序的稳定性和复杂度的度量。也称为MCC指标。通过计算程序模块的线性独立路径的数量来度量。
圈复杂度,在有些认证要求严格的行业做需要计算,比如汽车电子、工业安全类产品、医疗器械等,在这些行业里,可能需要严格的单元测试,单元测试还需要严格的覆盖率指标要求。那么计算覆盖率,就离不开这个圈复杂度的计算。
对于严格计算圈复杂度,比较枯燥,这里就简单的分享一下如何计算的一般步骤:
将所有条件通路绘制成控制流图
流图中每多一个圈,MCC值为流图中圈数+1。
比如:
这样一个流图,其MCC值为5。
对于更为详细的计算圈复杂度的方法,可以看看IBM的文档:
https://www.ibm.com/docs/en/raa/6.1?topic=metrics-cyclomatic-complexity
显然,圈复杂度较低的程序更容易理解,修改的风险也更小。
意面指数
度量一份代码是否有点意面风格,看到一个有意思的指数分享一下。
全局变量数目行数
CC为圈复杂度,函数内读写全局变量的数目,函数的行数。
当然,这个公式是否严谨,我也不清楚。但是按这个计算,如果数字越高,显然代码的风格就越差。得分越高的代码,风格越差,越长的像意面。
得分高的代码,大体上有这些弊端
很难维护
很难懂
几乎无法做单元测试
非常容易潜藏bug,而且测试代价极高
这样的代码,喊别人给你review也是极度痛苦崩溃的
.......
总结一下
意面虽好吃,但意面式代码还是要远离。本文分享一些个人的理解,尽量降低代码的圈复杂度,尽量少用全局变量,函数尽量别整太长。慢慢养成习惯,代码风格就会慢慢改善。
1.马上报名|“RISC-V嵌入式与物联网开发技术”研讨会-暨《深入理解RISC-V程序开发》作者见面会(深圳站)
2.开幕在即 | 6万㎡解锁未来6G/AIoT/智车/快充/封装/嵌入式技术,“十三香”工程师福利局大揭秘!
免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。