【业务功能篇30】代码重构--卫语句/idea内置工具抽象方法

news2024/11/27 8:26:20

业务场景: 当前我们项目在发布流水线的时候,codecheck 圈复杂度高于10的,或者14的,需要进行一些整改,

什么是圈复杂度?

圈复杂度(Cyclomatic complexity,CC)也称为条件复杂度,是一种衡量代码复杂度的标准,其符号为V(G)。

圈复杂度(Cyclomatic complexity)是一种代码复杂度的衡量标准,在1976年由Thomas J. McCabe, Sr. 提出,目标是为了指导程序员写出更具可测性和可维护性的代码。

它可以用来衡量一个模块判定结构的复杂程度,数量上表现为独立路径条数,也可以理解为覆盖所有可能的情况最少需要的测试用例数量。 

程序的可能错误和高的圈复杂度有着很大关系,圈复杂度最高的模块和方法,其缺陷个数也可能最多。

圈复杂度大说明程序代码的判断逻辑复杂,可能质量低,且难于测试和维护。

圈复杂度的计算方法

圈复杂度有两种计算方法:点边计算法和节点判定法。

节点判定法

圈复杂度的计算还有另外一种更直观的方法,因为圈复杂度所反映的是“判定条件”的数量,所以圈复杂度实际上就是等于判定节点的数量再加上1。

对应的计算公式为:V (G) = P + 1

其中 P 为判定节点数,常见的判定节点有:

  • if 语句
  • while 语句
  • for 语句
  • case 语句
  • catch 语句
  • and 和 or 布尔操作
  • ? : 三元运算符

对于多分支的 case 结构或 if - else if - else 结构,统计判定节点的个数时需要特别注意:必须统计全部实际的判定节点数,也即每个 else if 语句,以及每个 case 语句,都应该算为一个判定节点。

降低圈复杂度的方法

常用的方法有:

  • 简化、合并条件表达式
  • 将条件判定提炼出独立函数
  • 将大函数拆成小函数
  • 以明确函数取代参数
  • 替换算法

 

重构思路:圈复杂度高多层嵌套:卫语句,降低if嵌套层数

目前我们业务常用的重构优化,就是卫语句

卫语句(guard clauses)是一种改善嵌套代码的优化代码。将经过多级嵌套的代码使用卫语句优化之后,代码嵌套层数可以降低,因此改使用卫语句能降低代码的复杂程度。卫语句是通过对原条件进行逻辑分析,将某些要害(guard)条件优先作判断,从而简化程序的流程走向,因此称为卫语句。

有些嵌套判断语句,它们都是在 if 里面的条件是真的情况才执行,也就是说它们都是走的正常情况,才会导致这么无限嵌套下去,那么我们从反面思考是不是就可以终止这种情况呢?也就是我们把不正常的条件先摘出来处理,剩下的就都是正常情况了。这其实就是卫语句的思考模式,也就是逆向思考。卫语句可以减少 if-else 语句嵌套的情况出现

如求 100 以内同时是 3、4、5 的倍数的题,如果我们根据题目所说的老老实实地判断符合倍数的情况,将会写成这样(假设每个 if 语句只判断一个条件):

for (int i = 1; i <= 100; i++) {
            if (i%3 == 0){
                if (i%4 == 0){
                    if (i%5 == 0){
                        System.out.println(i);
                    }
                }
            }
}

这就是 “横放着的金字塔”,而如果我们逆向思考,从是 3、4、5 的倍数的反面思考,也就是哪些情况不是 3、4、5 的倍数,先把这些情况摘出来,然后结束本次循环,继续找下一个数。这样我们就能防止多层嵌套了:

for (int i = 1; i <= 100; i++) {
            if (i%3 != 0){
                continue;
            }
            if (i%4 != 0){
                continue;
            }
            if (i%5 != 0){
                continue;
            }
            System.out.println(i);
}

只有在上面三个条件都不成立的情况下,才会走到最后一步输出的语句。也就是排除那些不符合条件的情况,剩下的自然就是符合条件的了。希望通过这个小例子能让你明白到底什么是卫语句。

 重构思路:针对复杂度高的代码块抽象为方法

选中好需要重构的代码块内容,然后右键 refactor---> extract method   

idea会自动帮你把代码块抽象出一个公共方法,与此同时,如果文件上下文内有相似代码块,还会提示你是否一起重构, 我们也点击是,这样还可以把重复的代码块都一起抽象出来,直接调用方法,这样复杂度就一定程度会降低

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/662273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Leetcode60天带刷】day07哈希表——454.四数相加II , 383. 赎金信 ,15. 三数之和 , 18. 四数之和

题目&#xff1a;454.四数相加II 454. 四数相加 II 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a; 0 < i, j, k, l < nnums1[i] nums2[j] nums3[k] nums4[l] 0 …

进阶面向对象

面向对象的意义在于 将日常生活中习惯的思维方式引入程序设计中 将需求中的概念直观的映射到解决方案中 以模块为中心构建可复用的软件系统 提高软件产品的可维护性和可拓展性 类和对象是面向对象中的两个基本概念 类&#xff1a;指的是一类事务&#xff0c;是一个抽象的概…

【Python 随练】学生成绩等级划分

题目&#xff1a; 利用条件运算符的嵌套来完成此题&#xff1a;学习成绩 ≥ 90 分的同学用 A 表示&#xff0c;60-89 分之间的用 B 表示&#xff0c;60 分以下的用 C 表示。 简介&#xff1a; 在本篇博客中&#xff0c;我们将使用条件运算符的嵌套来划分学生成绩的等级。根据…

Redis安装说明(黑马程序员)

Redis安装说明&#xff08;黑马程序员&#xff09; 笔者的redis(Linux版)的下载链接地址&#xff1a;https://download.csdn.net/download/weixin_46411355/87926624 笔者的redis图形化桌面客户端&#xff0c;下载链接地址为&#xff1a;https://download.csdn.net/download/w…

朴素贝叶斯算法

文章目录 1. 贝叶斯定理2. 朴素贝叶斯2.1 朴素贝叶斯原理2.2 朴素贝叶斯适用范围2.3 朴素贝叶斯常用模型 3. 朴素贝叶斯算法的特点4. 朴素贝叶斯的Python应用5. 源码仓库地址 1. 贝叶斯定理 先验概率&#xff1a;即基于统计的概率&#xff0c;是基于以往历史经验和分析得到的结…

【事故致因】HFACS(人因分析与分类系统)

HFACS&#xff08;人因分析与分类系统&#xff09; 1 来源2 拟解决的问题&#xff08;背景&#xff09;2 基本架构2.1 Unsafe Acts2.1.1 Errors2.1.1.1 Skill-based errors2.1.1.2 Decision errors2.2.1.3 Perceptual errors 2.1.2 Violations2.1.2.1 Routine violations2.1.2.…

数学建模竞赛国赛入场券之攻略

数学建模竞赛国赛入场券之攻略 1.团队契合度 在3天的准备时间中&#xff0c;如果是临时组建的草台班子光处理分歧可能就已经耗掉一半时间&#xff0c;最好在赛前就完成磨合&#xff0c;像一起做模拟题练练手之类&#xff0c;甲准备图论、乙准备优化方法&#xff0c;然后再一块…

linux 内存管理之五bootmem 分配器 2.4.22

内核的bootmem 分配器 又叫自举内存分配器&#xff0c;其内涵即 自己初始化自己的一个内存分配器 其初始化过程 已在 上篇[ARM 架构物理内存初始化]&#xff0c;(https://blog.csdn.net/zsj1126/article/details/116430903)介绍 本文主要关注该分配器提供的主要接口和用途 st…

系统测试工程师的岗位职责描述(合集)

系统测试工程师的岗位职责描述1 职责&#xff1a; 1、评审产品或项目需求的测试性&#xff0c;评审产品或项目开发设计的合理性。 2、根据需求进行测试规划&#xff0c;制定测试方案&#xff0c;设计测试用例; 组织测试用例评审; 3、根据测试计划进行项目测试进度和测试质量的管…

Cesium 实战 - 自定义视频标签展示视频

Cesium 实战 - 自定义视频标签展示视频 视频材质核心代码气泡框视频核心代码在线示例 在封装 Cesium 工具的时候&#xff0c;偶然发现 Cesium 支持视频材质功能&#xff0c;虽然目前项目中还没有用到&#xff0c;但是提前做了功能封装&#xff0c;以后使用的时候会方便一些。 …

强化学习从基础到进阶-常见问题和面试必知必答[1]:强化学习概述、序列决策、动作空间定义、策略价值函数、探索与利用、Gym强化学习实验

【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧&#xff08;调参、画图等、趣味项目实现、学术应用项目实现 专栏详细介绍&#xff1a;【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧…

Triton教程---模型设置

Triton教程—模型设置 这是您第一次编写配置文件吗&#xff1f; 查看本指南或本示例&#xff01; 文章目录 Triton教程---模型设置最小模型配置名称、平台和后端模型交互策略解耦 最大批量大小输入和输出PyTorch 后端的特殊约定命名约定&#xff1a;张量字典作为输入&#xf…

用CSS3实现边框流动,让你的网页更有创意和个性

前言 边框流动动画是一种非常常见的效果&#xff0c;能够让网页看起来更加生动有趣。通过使用 CSS3&#xff0c;我们可以轻松地实现这种动画效果。本文将介绍如何使用 CSS3 实现边框流动效果&#xff0c;下面一起来看看吧。 实现效果 实现思路 首先我们先创建一个盒子容器&…

ENVI软件的地表温度(LST)反演教程

前言 遥感图像处理平台&#xff08;The Environment for Visualizing Images&#xff09;的软件处理技术覆盖图像数据的输入/输出、图像定标、图像增强、纠正、正射校正、镶嵌、数据融合以及各种变换、信息提取、图像分类、基于知识的决策树分类、与GIS的整合、DEM及地形信息提…

【FPGA入门】第四篇、有限状态机

目录 第一部分、一个关于有限状态机的例子 第二部分、学会有限状态机的准备知识 1、什么是有限状态机&#xff1f; 2、为什么需要状态机&#xff1f; 3、什么是竞争冒险&#xff1f; 3.1、什么情况下会发生竞争冒险&#xff1f; 3.2、为什么组合逻辑电路会产生竞争和冒险…

HBase入门(一)

第1章 HBase简介 1.1 HBase定义 HBase是一种分布式、可扩展、支持海量数据存储的NoSQL数据库。 1.2 HBase数据模型 逻辑上&#xff0c;HBase的数据模型同关系型数据库很类似&#xff0c;数据存储在一张表中&#xff0c;有行有列。但从HBase的底层物理存储结构&#xff08;…

【C语言复习】第四篇、有关C语言数据类型的知识

目录 第一部分、前言 第二部分、初识数据类型 1、C语言为啥要这么多的数据类型&#xff1f; 2、表格中所占内存的大小是如何计算得到的&#xff1f; 2.1、计算机的内数据存储单位 2.2、关键字sizeof的使用说明&#xff08;具体后面会更详细的解释&#xff09; 3、为什么…

【Python 随练】求最大公约数和最小公倍数

题目&#xff1a; 输入两个正整数 m 和 n&#xff0c;求其最大公约数和最小公倍数。 简介&#xff1a; 在本篇博客中&#xff0c;我们将解决一个常见的数学问题&#xff1a;求两个正整数的最大公约数和最小公倍数。我们将提供问题的解析&#xff0c;并给出一个完整的代码示例…

【新星计划Linux】——Linux介绍与了解Linux与Windows系统区别

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​ 目录 前言 一.Linux系统 1.Linux系统与Windows系统的区别 &#xff08;1&#xff09;性…

【JavaScript】ES6新特性(4)

14. Proxy 代理 Proxy 可以对目标对象的读取、函数调用等操作进行拦截&#xff0c;然后进行操作处理 它不直接操作对象&#xff0c;而是像代理模式&#xff0c;通过对象的代理对象进行操作&#xff0c;在进行这些操作时&#xff0c;可以添加一些需要的额外操作 14.1 Object.d…