java 圈复杂度_关于Java:降低Switch语句的循环复杂度-Sonar
我想减少开关盒的圈复杂度
我的代码是:
public String getCalenderName() {
switch (type) {
case COUNTRY:
return country == null ? name : country.getName() + HOLIDAY_CALENDAR;
case CCP:
return ccp == null ? name : ccp.getName() +" CCP" + HOLIDAY_CALENDAR;
case EXCHANGE:
return exchange == null ? name : exchange.getName() + HOLIDAY_CALENDAR;
case TENANT:
return tenant == null ? name : tenant.getName() + HOLIDAY_CALENDAR;
default:
return name;
}
}
此代码块的复杂度为16,并希望将其降低到10。
国家,ccp,交易所和租户是我的不同对象。 基于类型I将调用它们各自的方法。
"此代码复杂度为16,并且希望将其降低到10"为什么不将其降低到9? 还是8? 还是11? 为什么16有问题?
根据我的声纳规则,我希望将其降低到10以下,如果我们可以进一步降低它,那就太好了。 @安迪·特纳
@AmarMagar您是否忘记在每种情况下或故意添加中断语句? 我不确定添加中断语句是否有助于降低循环复杂性。
@克里希纳·昆塔拉(Krishna Kuntala)不需要break语句,因为在每种情况下他都将返回某些东西。
我相信这是一个Sonar警告。我认为Sonar警告不是必须执行的规则,而只是指导。您的代码块原为READABLE和MAINTAINABLE。它已经很简单,但是如果您真的想要更改它,可以尝试以下两种方法,看看复杂度是否降低了:
注意:我现在没有编译器,所以可能会出现错误,请对此表示抱歉。
第一种方法:
Map multipliers = new HashMap();
map.put("country", country);
map.put("exchange", exchange);
map.put("ccp", ccp);
map.put("tenant", tenant);
然后我们可以使用地图获取正确的元素
return map.get(type) == null ? name : map.get(type).getName() + HOLIDAY_CALENDAR;
第二种方法:
您所有的对象都有相同的方法,因此可以在其中添加Interface和getName()方法,并更改方法签名,例如:
getCalendarName(YourInterface yourObject){
return yourObject == null ? name : yourObject.getName() + HOLIDAY_CALENDAR;
}
已经尝试了第一种方法,但是无法在地图值上调用getName
然后使用第二种方法,引入一个带有getName()方法的新接口。如果您有共同的行为/方法,则应该使用多态的好处。
无论如何都以不同的方式找到了答案
据我所知,不要在switch语句中使用return语句。在switch语句后使用变量应用该逻辑。
创建一个用于检查空值的方法并从switch调用该方法,然后您将能够降低Cyclomatic Complexity
您可以用Dictionary>替换switch / case语句。
看看这个博客文章的最后一个例子
我认为您可以通过确保代码中的其他内容固定来降低复杂度。
举个例子:
case COUNTRY:
return country == null ? name : country.getName() + HOLIDAY_CALENDAR;
这意味着如果压延机类型为COUNTRY,则与压延机关联的国家/地区可能为null。这是您应设计避免的事情,因为我看不出为什么这可能是有效的情况。为什么您会有没有国家的国家日历?
因此,一旦为日历分配了type,请确保没有与日历关联的非空对象。这样,您的情况将像
case COUNTRY:
return country.getName() + HOLIDAY_CALENDAR;
将您的圈复杂度降低到5。
如果您的首要目标只是减少圈数的复杂性,则应针对每种获取名称的方式创建方法,如下所示。
public String getCalenderName() {
switch (type) {
case COUNTRY:
return getCountryName();
case CCP:
return getCcpName();
case EXCHANGE:
return getExchangeName();
case TENANT:
return getTenantName();
default:
return name;
}
}
private String getCountryName() {
return country == null ? name : country.getName() + HOLIDAY_CALENDAR;
}
private String getCcpName() {
return ccp == null ? name : ccp.getName() +" CCP" + HOLIDAY_CALENDAR;
}
private String getExchangeName() {
return exchange == null ? name : getName.toString() + HOLIDAY_CALENDAR;
}
private String getTenantName() {
return tenant == null ? name : getName.toString() + HOLIDAY_CALENDAR;
}
请注意,在您的特定示例中,我假设您有1个类收集(至少)4个非常相似的行为。重构无疑会更有意义,例如具有一个基本实现(是否抽象)以及其他4个继承的类。
当然,如果您不想让声纳抱怨,请添加javadoc;)
如果您的对象:国家/地区,cpp,交易所和租户共享同一接口,例如您可以使用ObjectWithGetName重构代码,如下所示:
public String getCalenderName() {
ObjectWithGetNameMethod calendarType = null;
switch (type) {
case COUNTRY:
calendarType = country;
break;
case CCP:
calendarType = cpp;
break;
case EXCHANGE:
calendarType = exchange;
break;
case TENANT:
calendarType = tenant;
break;
default:
calendarType = null;
}
return (calendarType != null ? (calendarType.getName() + HOLIDAY_CALENDAR) : name);
}
我也认为将开关切换到单独的方法会很好,因为看起来巫婆会在许多不同的地方使用。
该解决方案不起作用,因为国家/地区,抄送,交易所和租户是不同的实体。因此,在调用getName方法时,我必须使用它们各自的对象来调用方法。
您可以删除所有空比较,并在切换大小写之前对其进行检查。在这种情况下,复杂度将减少4倍或更多。
尝试仍然无法减少
public String getName() {
if (type == null) {
return name;
}
if (type == BusinessCalendarType.COUNTRY) {
return country == null ? name : country.getName() + HOLIDAY_CALENDAR;
} else if (type == BusinessCalendarType.CCP) {
return ccp == null ? name : ccp.getName() +" CCP" + HOLIDAY_CALENDAR;
} else if (type == BusinessCalendarType.EXCHANGE) {
return exchange == null ? name : exchange.getName() + HOLIDAY_CALENDAR;
} else if (type == BusinessCalendarType.TENANT) {
return tenant == null ? name : tenant.getName() + HOLIDAY_CALENDAR;
} else {
return name;
}
}
这对我有用
这在功能上是错误的。 swicht语句中的默认值不对应于type == null
实际上type是一个Enum,并且肯定会返回这4个值之一或仅返回null。在我的问题中,我写了默认声明,这是因为声纳警告。反正你是对的。根据您的建议,我已经更改了此答案。
您只是为了使声纳中的警告规则更难阅读而使相对(人类)可读的功能变得更加难以理解...
java 圈复杂度_关于Java:降低Switch语句的循环复杂度-Sonar相关推荐
- java项目----教务管理系统_基于Java的教务管理系统
java项目----教务管理系统_基于Java的教务管理系统 2022-04-22 18:18·java基础 最近为客户开发了一套学校用教务管理系统,主要实现学生.课程.老师.选课等相关的信息化管理功 ...
- java switch语句套循环_java中switch语句和循环语句的使用
java中switch语句和循环语句的使用 发布时间:2020-06-17 10:49:18 来源:亿速云 阅读:121 作者:Leah 这篇文章运用简单易懂的例子给大家介绍java中switch语句 ...
- java是什么格式_是java格式
错误:编码GBK的不可映射字符的解决办法 最近在重新补javaSE的基础,编辑器编写完代码以后,在控制台运行代码段的时候,出现了以下的错误提示:错误:编码GBK的不可映射字符 在通过查询谷哥和度娘以后 ...
- JAVA redis缓存过期_失效java服务器
Java 并发/多线程教程--4并发模型 本系列译自jakob jenkov的Java并发多线程教程(本章节部分内容参考http://ifeve.com/并发编程模型),个人觉得很有收获.由于个人水平 ...
- java string最大长度_一个Java字符串中到底有多少个字符?
作者:鸟窝 依照Java的文档, Java中的字符内部是以UTF-16编码方式表示的,最小值是 (0),最大值是(65535), 也就是一个字符以2个字节来表示,难道Java最多只能表示 65535个 ...
- java语言程序设计答案_《java语言程序设计》练习题及答案
<java语言程序设计>练习题及答案 JAVA 语言程序设计题及部分答案 一.单选题:(每题1分)下列各题A).B).C).D)四个选项中, 只有一个选项是正确的,请将正确选项的标记写在题 ...
- java ee开发环境_设置Java EE 6开发环境
java ee开发环境 本教程简要说明了如何设置典型的环境来开发基于Java EE 6的应用程序. 除了可以正常工作的Windows XP客户端具有足够的CPU能力和内存外,本教程没有其他先决条件. ...
- java代码耗尽内存_有关Java内存溢出及内存消耗的小知识
内存溢出原理: 我们知道,Java程序本身是不能直接在计算机上运行的,它需要依赖于硬件基础之上的操作系统和JVM(Java虚拟机). Java程序启动时JVM都会分配一个初始内存和最大内存给这个应用程 ...
- java的基本结构_【Java基础】基本程序设计结构
摘自<Java核心技术 卷一> 希望能有自己的理解融入书中,融会贯通. 1.数据类型 1.1.JAVA中的基本类型 1.1.1.基本类型及其占用字节.默认值 注释:8bit = 1byte ...
最新文章
- 滴滴自动驾驶部门成立独立公司,CTO张博兼任新公司CEO
- [NOI2002] 银河英雄传说(带权并查集好题)
- Python网络爬虫 - 一个简单的爬虫例子
- 【工业4.0】深度报告:独家解密工业4.0真正图谋?跟踪软件帝国的十年
- 项目总设计师应做好设计控制
- Python3之redis使用
- 汇编指令 DUP指令
- mysql having实例_Mysql必读mysql group by having 实例代码
- 微软概述 Windows Server 2008 的定价、包装及授权
- Sql Server之旅——终点站 nolock引发的三级事件的一些思考
- C++ 多态之虚析构与纯虚拟购01
- react 组件引用组件_自定位React组件
- BZOJ3832: [Poi2014]Rally(拓扑排序 堆)
- [置顶] java高级工程师-----struts的内部运行机制详解
- iPad怎么截屏?iPad快速截图的7种方式
- 计算机信息管理发展的重要性,建设计算机信息管理系统的意义和目标
- python定义空数组_python定义二维数组
- cordon,drain
- office使用技巧大全
- 财报汇总 | 可口可乐、埃森哲、圆通、海亮教育等9家企业发布业绩
热门文章
- linux 内核编译错误 .size expression for copy_user_generic_c does not evaluate to a constant
- RASPBERRY PI 3 MODEL B 安装使用
- Android数据存储
- python创建一个字典、关键字为只包含字母的字符串_探究Python源码,终于弄懂了字符串驻留技术...
- 用mysql命令还原_mysql——数据还原——使用mysql命令还原
- 使用 8 位 YUV 格式的视频呈现
- 写一个不能被继承的类(友元的不可继承性)
- java可以入侵电脑系统吗_如何通过tomcat入侵远程计算机系统
- go文件服务器mimetype,网络:什么是 MIME TYPE?
- 华为手机获取状态栏高度是错误的_华为后置指纹这么多功能,你不会还以为只能解锁和支付吧...