笔者基本不写基础类的文章,主要是看掘金的大佬们写的很全面了,没必要班门弄斧。而关于圈复杂度,有文章讲了原理、有文章讲了插件、有文章讲了如何用它优化代码,纵观下来是能 get 到了圈复杂度的好处,但没有讲出足够的动机,为什么要去用,不用不也一样开发的好好的。
起因
写这篇文章,其实也是有三个场景来提升自己的写作动机:
场景一
笔者在做前端开发时,很早就已经习惯在VS Code 上使用CodeMetrics 扩展插件时时监测自己的代码是否优雅,这个插件真的十分好用,以至于在用其他 IDE 或者写其他语言代码时,总想着找下有没有类似的插件能力。
而且很重要的一点,这个插件会时时的提醒你的代码很酷。
场景二
去年翻看公司前端编辑器内核代码时,发现了如下的一段血腥地狱(哈,当然是直译,bloody hell 翻译过来是该死的意思):
血腥地狱这个词真的是名副其实,想看懂这段代码,就要有我不入地狱,谁入地狱的心态。
场景三
今年的事,发现一个同事,把推荐给他的CodeMetrics又关掉了,原因是它右侧花花绿绿的看着不舒服,红色的还会跟 git 的插件发生冲突。
思维定式,也不想强制自己去优化代码,看着红的黄的也难受。
洞察
以上举了3个小场景,其实对应着你为什么要想着去用它的3个动机:自律 、律他 、规范。
自律
不光是新人,我刚入这行的前几年也是在思考,什么样的代码是优雅 的,什么样的架构是合理的。
是去套各个大佬的实现还是用上各种设计模式?那其实是学了结果,而没有学到过程。为什么会有那么多设计模式?其实都是被逼出来的,试试看,强制自己的代码方法内圈复杂度低于 10,你就自然会去找各种方式来优化代码,而这各种方式后面你再仔细看看,其实都有各种设计模式的影子。
- 工厂模式可以把一段复杂的对象创建过程封装在工厂方法中,降低了调用这个方法的代码的圈复杂度。
- 策略模式如果有一段代码中包含大量的if-else条件判断,这将导致很高的圈复杂度。使用策略模式,可以把每个条件分支封装在一个策略类中,然后在运行时动态选择使用哪个策略,这样就能大大降低原本代码的圈复杂度。
- 命令模式可以把每个操作封装为一个命令对象,然后用一个命令队列来按顺序执行这些命令。这样一来,原本复杂的方法就被拆分成了一系列简单的命令,每个命令的圈复杂度都很低。
- 观察者模式可以避免在一个类中包含大量的代码来检查和更新其他类的状态,从而降低这个类的圈复杂度。
- ...
当然,这个被逼也不能去违背基本 SOLID 原则,我们是要代码优雅,不是陷入疯狂。
SOLID
- 单一职责原则(Single Responsibility Principle, SRP)
- 开放封闭原则(Open Closed Principle, OCP)
- 里氏替换原则(Liskov Substitution Principle, LSP)
- 接口隔离原则(Interface Segregation Principle, ISP)
- 依赖倒置原则(Dependency Inversion Principle, DIP)
律他
朋友们啊,如何在接手一个项目时,最短时间判断它是一坨💩,没啥抢救的必要了,来占领道德的至高点,难不成要把整个项目去尝一遍吗??!!
这时候你用上圈复杂度,打开几个核心的代码,看看他们红红黄黄的提醒颜色,甚至里面藏着拔舌地狱 、刀山地狱 、油锅地狱【手动滑稽】... 那还用继续看吗,咱就说也不必那么头铁,要不就推到重写,要不就千万别动它(十年程序员的经验:处理一坨屎最好的方式就是埋地里做肥料,而不是拿出来炒)。
当然,除了接手项目外,多人合作项目上更常用,毕竟大家都在一个项目里,对同事更严格其实是对自己更好,谁知道他埋的雷会不会炸到你。从代码的角度看,如果一个雷的圈复杂度小于10,那相当于摔炮级别的,问题查找、修改起来都很容易。相对的,一个超过圈复杂度超过50的雷,那就和去拆有50条引线的炸弹一样,一不小心就炸的自己面目全非。
所以,除非是已经有提桶跑路的念头了,那为了自己干的舒心,好的做法是让合作的同事也重视起来。
规范
无论自律 也好,他律 也好,最难的是持之以恒,就和减肥一样。那进一步就是形成团队规范 ,除了在开发时使用扩展插件外,在提交代码前也可以 hook 提交流程,进行圈复杂度的检查拦截。当然在当下,我们还可以结合 AI 进行 git 代码合并前审查,比如 pr-agent、snyk 等,这些工具不仅可以进行复杂度检测,还可以分析错误和漏洞,以及你的代码变量方法命名是否合理。
总结
我一直认为,一个好的程序员是让复杂的事情变简单,其实这在各行各业也同理,比如稿定:让设计更简单。
但其实社会是人性的,不然也不会有防御性编程 ,代码壁垒这种做法了【手动狗头】。
当然,做人最重要的是开心,壁垒是对外的,对自己还是清晰简单优雅的代码更舒心不是 ~
感谢阅读,如果对你有用请点个赞 ❤️