java 该方法的圈复杂度大于授权
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37046882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
The Cyclomatic Complexity of this method is greater than authorized
提问by Shiladittya Chakraborty
I am using below method for checking null or empty field:
我正在使用以下方法检查空字段或空字段:
public boolean isVoNotNull(){
return null != this.cardNo && StringUtils.isNotBlank(this.cardNo)
&& null != this.otp && StringUtils.isNotBlank(this.otp)
&& null != this.password && StringUtils.isNotBlank(this.password)
&& null != this.userid && StringUtils.isNotBlank(this.userid)
&& null != this.type && StringUtils.isNotBlank(this.type)
&& null != this.walletMobileNo && StringUtils.isNotBlank(this.walletMobileNo);
}
But getting below exception while this code is validating with SonarLint
但是在此代码使用 SonarLint 验证时低于异常
EXCEPTION : The Cyclomatic Complexity of this method "isVoNotNull" is 12 which is greater than 10 authorized.
例外:此方法“isVoNotNull”的圈复杂度为 12,大于 10。
How can I solve this exception or how can I remove the complexity from the code?
如何解决此异常或如何从代码中消除复杂性?
回答by BalusC
You need to analyze duplicated code and refactor it into a reusable method.
您需要分析重复的代码并将其重构为可重用的方法。
Given your original snippet,
鉴于您的原始片段,
public boolean isVoNotNull() {
return null != this.cardNo && StringUtils.isNotBlank(this.cardNo)
&& null != this.otp && StringUtils.isNotBlank(this.otp)
&& null != this.password && StringUtils.isNotBlank(this.password)
&& null != this.userid && StringUtils.isNotBlank(this.userid)
&& null != this.type && StringUtils.isNotBlank(this.type)
&& null != this.walletMobileNo && StringUtils.isNotBlank(this.walletMobileNo);
}
we can identify the following repetitive part:
我们可以识别出以下重复部分:
null != this.xxx && StringUtils.isNotBlank(this.xxx)
Given that StringUtils#isNotBlank()
alreadychecks for null
, we can further simplify it.
鉴于StringUtils#isNotBlank()
已经检查了null
,我们可以进一步简化它。
StringUtils.isNotBlank(this.xxx)
Given that you need to invoke this a variable number of times, best would be to refactor it to a method taking a variable number of argumentswhich checks them all in a loop.
鉴于您需要多次调用它,最好将其重构为一个方法,该方法采用可变数量的参数,在循环中检查所有参数。
public static boolean isNoneBlank(String... strings) {
for (String string : strings) {
if (!StringUtils.isNotBlank(string)) {
return false;
}
}
return true;
}
Or if you're already on Java 8 with Streams and Lambdasupport:
或者,如果您已经使用支持Streams 和 Lambda 的Java 8 :
public static boolean isNoneBlank(String... strings) {
return Arrays.stream(strings).allMatch(StringUtils::isNotBlank);
}
Now you can make use of it as below:
现在你可以使用它如下:
public boolean isVoNotNull() {
return isNoneBlank(this.cardNo, this.otp, this.password, this.userid, this.type, this.walletMobileNo);
}
You could further reduce the boilerplate by removing the unnecessary this
.
您可以通过删除不必要的this
.
public boolean isVoNotNull() {
return isNoneBlank(cardNo, otp, password, userid, type, walletMobileNo);
}
This all was an appliance of the Don't Repeat Yourself (DRY)software engineering principle.
这一切都是“不要重复自己”(DRY)软件工程原则的应用。
That said, as msandifordpointed out, it turns out that Apache Commons Lang StringUtils
has since version 3.2 alreadyexactly this method. So if you don't have it yet, consider upgrading Apache Commons Lang to at least 3.2.
也就是说,正如msandiford指出的那样,事实证明,Apache Commons LangStringUtils
从 3.2 版开始就已经采用了这种方法。因此,如果您还没有它,请考虑将 Apache Commons Lang 升级到至少 3.2。
public boolean isVoNotNull() {
return StringUtils.isNoneBlank(cardNo, otp, password, userid, type, walletMobileNo);
}
回答by clstrfsck
As others have pointed out the null
check is redundant as isNotBlank
checks this too.
正如其他人指出的那样,null
检查也是多余的,因为isNotBlank
检查这也是。
So, if you are using Apache StringUtils 3.2 or later, you can just use StringUtils.isNoneBlank(...)
因此,如果您使用的是 Apache StringUtils 3.2 或更高版本,则可以只使用StringUtils.isNoneBlank(...)
public boolean isVoNotNull() {
return StringUtils.isNoneBlank(cardNo, otp, password, userid, type, walletMobileNo);
}
If you are using an earlier version, you could easily write one:
如果您使用的是早期版本,则可以轻松编写一个:
public static boolean isNoneBlank(CharSequence... seqs) {
for (CharSequence seq : seqs) {
if (StringUtils.isBlank(seq))
return false;
}
return true;
}
Or in Java 8:
或者在 Java 8 中:
public static boolean isNoneBlank(CharSequence... seqs) {
return Stream.of(seqs).allMatch(StringUtils::isNotBlank);
}
回答by CoffeDeveloper
Add the strings to an array and check with a loop for nullity and not blank-ness. Worst performance of course but should break that non-sensed limit.
将字符串添加到数组中,并使用循环检查是否为空而不是空白。当然是最差的表现,但应该打破非感知限制。
Example code:
示例代码:
public boolean isVoNotNull(){
string [] stringsToCheck = new string[]{
this.cardNo,
this.otp,
// ...
}
//return CheckStringArrayNotNull(stringsToCheck);
return StringUtils.isNoneBlank(stringsToCheck);
}
// high chance this method already exists inside StringUtils
// INFACT FOUND! :)
private boolean CheckStringArrayNotNull( string [] stringsToCheck){
for(int i=0; i<stringsToCheck.length(); i++)
if( StringUtils.isNotBlank( stringsToCheck[i]) == false)
return false;
return true;
}
or even better, (EDIT: seems @msandiford beat me on time for this solution)
甚至更好,(编辑:似乎@msandiford 在此解决方案上按时击败了我)
public boolean isVoNotNull(){
return StringUtils.isNoneBlank(cardNo, otp, ...);
}
You could of course break into more methods to reduce cyclomatic complexity but that makes the class even harder to read and understand. Code metrics should be used only to investigate problems, not as a development mantra, for example I can take a very stupid class with 100 methods each with Cyclomatic complexity of 100 and refactor it so that it has perfect code metrics but is impossible to understand. Never look at code metrics, think to good solutions without using coding metrics.
您当然可以分解成更多方法来降低圈复杂度,但这会使该类更难以阅读和理解。代码度量应该仅用于调查问题,而不是作为开发准则,例如我可以将一个非常愚蠢的类包含 100 个方法,每个方法的圈复杂度为 100 并对其进行重构,使其具有完美的代码度量,但无法理解。永远不要看代码度量,在不使用代码度量的情况下考虑好的解决方案。
回答by Troncador
StringUtils.isNotBlank
StringUtils.isNotBlank
"Checks if a CharSequence is not empty (""), not null and not whitespace only."
“检查 CharSequence 是否不为空(“”)、不为空且不为空白。”
The function already check if the object is null, then you can simplify
该函数已经检查对象是否为空,那么您可以简化
public boolean isVoNotNull() {
return StringUtils.isNotBlank(this.cardNo)
&& StringUtils.isNotBlank(this.otp)
&& StringUtils.isNotBlank(this.password)
&& StringUtils.isNotBlank(this.userid)
&& StringUtils.isNotBlank(this.type)
&& StringUtils.isNotBlank(this.walletMobileNo);
}
To reduce the number of conditional operators, you can do something like this:
要减少条件运算符的数量,您可以执行以下操作:
public boolean isVoNotNull(){
Boolean[] condition = new Boolean[] {
StringUtils.isNotBlank(this.cardNo),
StringUtils.isNotBlank(this.otp),
StringUtils.isNotBlank(this.password),
StringUtils.isNotBlank(this.userid),
StringUtils.isNotBlank(this.type),
StringUtils.isNotBlank(this.walletMobileNo)
};
return BooleanUtils.and(condition);
}
Maybe is a little tricky, but it work
也许有点棘手,但它有效