当前位置:网站首页>重构指标之如何监控代码圈复杂度
重构指标之如何监控代码圈复杂度
2022-08-04 18:59:00 【京东云开发者】
1 引言
软件应用在发展到适当时机,”重构”,是开发过程中不可避免需要进行的一项工作。重构代码,以适配当前模块设计之初未考虑到的多样化场景,并增加模块的可维护性、健壮性、可测试性。那么,如何明确重构的方向,以及量化重构的结果呢?代码圈复杂度可以是一个供选择的指标。下文介绍如何获取应用的代码圈复杂度做到线上监控,给到复盘程序复杂程度的数据支撑。
2 背景知识
2.1 圈复杂度
圈复杂度(Cyclomatic complexity,简写CC)也称为条件复杂度,是一种代码复杂度的衡量标准。由托马斯·J·麦凯布(Thomas J. McCabe, Sr.)于1976年提出,用来表示程序的复杂度,其符号为VG或是M。它可以用来衡量一个模块判定结构的复杂程度,数量上表现为独立现行路径条数,也可理解为覆盖所有的可能情况最少使用的测试用例数。圈复杂度大说明程序代码的判断逻辑复杂,可能质量低且难于测试和维护。程序的可能错误和高的圈复杂度有着很大关系。
2.2 圈复杂度计算方式
常用结构圈复杂度计算
- 顺序结构:顺序结构复杂度为1。
- if-else-else、switch-case:每增加一个分支,复杂度增加1,&& 、|| 运算也为一个分支。
- 循环结构:增加一个循环结构,复杂度增加1。
- return:增加一条return语句,复杂度将加1。
2.3 圈复杂度度量标准
如上列出行业内相对认可的度量数据,实际这个完全是看自己的业务体量和项目情况来决定的。假设你的业务很简单,而且是个单体应用,功能都是很简单的CRUD,那你的圈复杂度即使想上去也没有那么容易。此时你就可以选择把圈复杂度的重构阈值设定为10.
假设你的业务十分复杂,而且涉及到多个其他的微服务系统调用,再加上各种业务中的corner case的判断,圈复杂度上100可能都不在话下。
2.4 降低圈复杂度方法
1)函数提炼与拆分,单一职责
- 拆分成子函数
- 每个函数要有明确的功能实现,不要为了追求行数少而合并功能实现
- 逻辑模块和数据模块要区分开编写
2)优化算法
- 减少不必要条件、循环分支,尽量少用 if …else … ,采用三元表达式替换if else
3)表达式逻辑优化
- 合并条件表达式,比如使用a || b || c
4)减少提前return
3 方案概述
3.1 脚本设计
1)开发语言
- python
2)依赖环境
- lizard
- APScheduler
- smtplib
- pymysql
3)脚本架构
3.2 功能介绍
1)支持检索语言范围:
支持15种开发语言,包含常用语言如下
- C/C++ (works with C++14)
- Java
- C# (C Sharp)
- JavaScript (With ES6 and JSX)
- Python
- Golang
2)扫描参数配置说明:
利用lizard执行扫描,常用命令如下:
配置检查范围:
- 列出要分析的编程语言。如果留空,将搜索支持的所有语言。
-l LANGUAGES,--languages LANGUAGES
- 排除与模式匹配的文件。匹配一切?匹配任何单个字符,“/folder/”递归地排除文件夹中的所有内容。可以指定多个模式。不要忘了在模式周围加“”号。
-x EXCLUDE,--exclude EXCLUDE
- 设置白名单, 默认’./whitelizard.txt’
-W WHITELIST,--whitelist WHITELIST
配置阀值警告:
- 圈复杂度数警告的阈值,默认值为15,>15会产生警告。
-C CCN,--CCN CCN
- 设置字段的限制数。可以代码行数,圈复杂度,令牌数,参数数或自定义字段。如果函数设置超过了限制数会报警。
-T THRESHOLDS,--Threshold THRESHOLDS
配置报告输出:
- 根据格式输出到文件
-o OUTPUT_FILE,--output_file OUTPUT_FILE
官网地址:http://www.lizard.ws
源码地址:https://github.com/terryyin/lizard
3)定时执行扫描任务:
- 通过BackgroundScheduler创建调度任务,自动触发扫描方法,结果写库
def dojob():
scheduler =BackgroundScheduler()
scheduler.add_job(func,"cron", hour=21, minute=30)
scheduler.start()
3.3 结果展示
3.3.1 报告名词解释
- Cyclomatic complexity,圈复杂度也就是分支复杂度,最好保持在15 以下,目前脚本设置阀值10。
- LOC,包含注释的代码行数,目前设置200阀值。
- Token count ,token的个数,一个程序最多可以有 8192 个令牌, 每个令牌都是一个词,例如关键字,标识符,常量,标点符号,操作符。 对括号和字符串计数作为 1 个令牌。 逗号、句点、LOCAL、分号、END 和注释不计算在内。
- Parameter count,参数统计就是函数的参数个数,目前脚本设置阀值10。
3.3.2 执行结果展示
- Windows环境运行脚本,输入file_root(文件地址)执行扫描,支持自动弹出浏览器展示本次运行的Html报告
- 每周定期执行,按照系统维度扫描,支持触发邮件通知对应系统研发查看超过阀值方法名称
3.3.3 应用数据监控
- 每周定期拉取指定分支最新代码,执行文件分析,存储扫描结果,通过数据图表展示
4 总结
对于软件代码好坏的衡量,圈复杂度可以作为一个参考指标,研发可以通过提炼拆分函数、优化算法、优化逻辑表达式等方法降低模块(函数)圈复杂度。以上阐述圈复杂度一种线上监控方法,利用好线上化数据,结合现有团队项目情况,才能形成更好的实践机制。
边栏推荐
- 实验室专利书写指南
- 《学会写作》粥佐罗著
- 老电脑怎么重装系统win10
- win10 uwp slider 隐藏显示数值
- 什么是网站监控,网站监控软件有什么用?
- ELECTRA:Pre-training Text Encoders as Discriminators Rather Than Generators
- win10 uwp win2d 使用 Path 绘制界面
- [Distributed Advanced] Let's fill in those pits in Redis distributed locks.
- VPC2187/8 current mode PWM controller 4-100VIN ultra-wide voltage startup, highly integrated power control chip recommended
- 猜数字游戏
猜你喜欢
查询APP Store已发布过的版本记录
Redis数据库—定义、特点、安装、如何启动与停止
ECCV 2022 | FPN错位对齐,实现高效半监督目标检测(PseCo)
面试官:MVCC是如何实现的?
Day018 继承
openharmony代码框架初识(2)
机器学习之支持向量机实例,线性核函数 多项式核函数 RBF高斯核函数 sigmoid核函数
Alibaba Cloud International Edition uses ROS to build WordPress tutorial
从零开始实现一个简单的CycleGAN项目
After EasyCVR is locally connected to the national standard device to map the public network, the local device cannot play and cascade the solution
随机推荐
openharmony代码框架初识(2)
目标检测的发展与现状
老电脑怎么重装系统win10
如何进行自动化测试?
win10 uwp slider 隐藏显示数值
A group of friends asked for help, but the needs that were not solved in a week were solved in 3 minutes?
迪赛智慧数——其他图表(主题河流图):近年居民消费、储蓄、投资意愿
【填空题】130道面试填空题
【STM32】入门(五):串口TTL、RS232、RS485
Regardless of whether you are a public, professional or non-major class, I have been sorting out the learning route for a long time here, and the learning route I have summarized is not yet rolled up
从零开始实现一个简单的CycleGAN项目
方法的重写
C#爬虫之通过Selenium获取浏览器请求响应结果
入选爱分析·银行数字化厂商全景报告,网易数帆助力金融数字化场景落地
网络运维管理从基础到实战-自用笔记(1)构建综合园区网、接入互联网
【STM32】STM32单片机总目录
如何进行自动化测试?
#yyds干货盘点# 面试必刷TOP101:链表相加(二)
作业8.3 线程同步互斥机制条件变量
什么是网站监控,网站监控软件有什么用?