java圈复杂度_关于Java:降低Switch语句的循环复杂度-
java switch case stringSonar
我想减少开关盒的圈复杂度
我的代码是:
public String getCalenderName() {
switch (type) {
case COUNTRY:
return country == null ? name : Name() + HOLIDAY_CALENDAR;
case CCP:
return ccp == null ? name : Name() +" CCP" + HOLIDAY_CALENDAR;
case EXCHANGE:
return exchange == null ? name : Name() + HOLIDAY_CALENDAR;
case TENANT:
return tenant == null ? name : Name() + 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);
然后我们可以使⽤地图获取正确的元素
(type) == null ? name : (type).getName() + HOLIDAY_CALENDAR;
第⼆种⽅法:
您所有的对象都有相同的⽅法,因此可以在其中添加Interface和getName()⽅法,并更改⽅法签名,例如:
getCalendarName(YourInterface yourObject){
return yourObject == null ? name : Name() + HOLIDAY_CALENDAR;
}
已经尝试了第⼀种⽅法,但是⽆法在地图值上调⽤getName
然后使⽤第⼆种⽅法,引⼊⼀个带有getName()⽅法的新接⼝。如果您有共同的⾏为/⽅法,则应该使⽤多态的好处。
⽆论如何都以不同的⽅式到了答案
据我所知,不要在switch语句中使⽤return语句。在switch语句后使⽤变量应⽤该逻辑。
创建⼀个⽤于检查空值的⽅法并从switch调⽤该⽅法,然后您将能够降低Cyclomatic Complexity
您可以⽤Dictionary>替换switch / case语句。
看看这个博客⽂章的最后⼀个例⼦
我认为您可以通过确保代码中的其他内容固定来降低复杂度。
举个例⼦:
case COUNTRY:
return country == null ? name : Name() + HOLIDAY_CALENDAR;
这意味着如果压延机类型为COUNTRY,则与压延机关联的国家/地区可能为null。这是您应设计避免的事情,因为我看不出为什么这可能是有效的情况。为什么您会有没有国家的国家⽇历?
因此,⼀旦为⽇历分配了type,请确保没有与⽇历关联的⾮空对象。这样,您的情况将像
case COUNTRY:
Name() + HOLIDAY_CALENDAR;
将您的圈复杂度降低到5。
如果您的⾸要⽬标只是减少圈数的复杂性,则应针对每种获取名称的⽅式创建⽅法,如下所⽰。
public String getCalenderName() {
switch (type) {
case COUNTRY:
return getCountryName();
case CCP:
return getCcpName();
case EXCHANGE:
return getExchangeName();
case TENANT:
return getTenantName();
return name;
}
}
private String getCountryName() {
return country == null ? name : Name() + HOLIDAY_CALENDAR;
}
private String getCcpName() {
return ccp == null ? name : Name() +" CCP" + HOLIDAY_CALENDAR;
}
private String getExchangeName() {
return exchange == null ? name : String() + HOLIDAY_CALENDAR;
}
private String getTenantName() {
return tenant == null ? name : String() + 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;
default:
calendarType = null;
}
return (calendarType != null ? (Name() + HOLIDAY_CALENDAR) : name);
}
我也认为将开关切换到单独的⽅法会很好,因为看起来巫婆会在许多不同的地⽅使⽤。
该解决⽅案不起作⽤,因为国家/地区,抄送,交易所和租户是不同的实体。因此,在调⽤getName⽅法时,我必须使⽤它们各⾃的对象来调⽤⽅法。
您可以删除所有空⽐较,并在切换⼤⼩写之前对其进⾏检查。在这种情况下,复杂度将减少4倍或更多。
尝试仍然⽆法减少
public String getName() {
if (type == null) {
return name;
}
if (type == BusinessCalendarType.COUNTRY) {
return country == null ? name : Name() + HOLIDAY_CALENDAR;
} else if (type == BusinessCalendarType.CCP) {
return ccp == null ? name : Name() +" CCP" + HOLIDAY_CALENDAR;
} else if (type == BusinessCalendarType.EXCHANGE) {
return exchange == null ? name : Name() + HOLIDAY_CALENDAR;
} else if (type == BusinessCalendarType.TENANT) {
return tenant == null ? name : Name() + HOLIDAY_CALENDAR;
} else {
return name;
}
}
这对我有⽤
这在功能上是错误的。 swicht语句中的默认值不对应于type == null
实际上type是⼀个Enum,并且肯定会返回这4个值之⼀或仅返回null。在我的问题中,我写了默认声明,这是因为声纳警告。反正你是对的。根据您的建议,我已经更改了此答案。
您只是为了使声纳中的警告规则更难阅读⽽使相对(⼈类)可读的功能变得更加难以理解...
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论