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)缩小提前 return3
计划概述 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/l…
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 总结
对于软件代码好坏的掂量,圈复杂度能够作为一个参考指标,研发能够通过提炼拆分函数、优化算法、优化逻辑表达式等办法升高模块(函数)圈复杂度。以上论述圈复杂度一种线上监控办法,利用好线上化数据,联合现有团队我的项目状况,能力造成更好的实际机制。