降低圈复杂度
Cyclomatic Complexity reduction
我有一段代码在降低圈复杂度方面遇到了问题。由于必须匹配多个条件,我不确定进一步分解它的最佳方法。使事情复杂化的是,在其中两种情况下创建了一个新对象,但在第三种情况下却没有(它调用了另一个方法)。这是伪代码:
if (!cond3 && !cond1 && cond2 && cond4) {
// actions to perform
calculateValues();
return result;
} else if (!cond1 && cond2 && cond3) {
// actions to perform
Object result = new Result();
return result;
} else if (!cond4 && cond3 && cond1 && cond5) {
// actions to perform
Object result = new Result();
return result;
} else {
// throw error because inputs are invalid
}
通过提取方程的公共部分作为新变量,您可以将圈复杂度降低到 11
boolean common = !cond1 && cond2;
...
if (!cond3 && common && cond4) {
// actions to perform
calculateValues();
return result;
} else if (common && cond3) {
// actions to perform
Object result = new Result();
return result;
} else if (!cond4 && cond3 && cond1 && cond5) {
// actions to perform
Object result = new Result();
return result;
} else {
// throw error because inputs are invalid
}
您应该重构该代码,使用方法来抽象那些条件,高圈表示代码需要重构。例如,假设:!cond4 && cond3 && cond1 && cond5
测试登录用户是否有车,那么您应该将该条件组合重构为一个方法:
private boolean loggedUserHasCar() {
return !cond4 && cond3 && cond1 && cond5;
}
对其他条件做同样的事情。 if
带有 4 个条件的语句很难阅读。提取这些语句将降低您的方法圈复杂度并使您的代码更具可读性
我对您的问题很感兴趣,并尝试了较早提出的解决方案,其中提取条件以分离像这样的方法
public class Test {
public static void main(String[] args) {
cyclometricComplexityTest();
}
static boolean cond1 = true;
static boolean cond2 = true;
static boolean cond3 = true;
static boolean cond4 = true;
static boolean cond5 = true;
public static Object cyclometricComplexityTest() {
if (isBoolean1()) {
// actions to perform
Object result = null;
calculateValues();
return result;
} else if (isBoolean2()) {
// actions to perform
Object result = new Result();
return result;
} else if (isBoolean3()) {
// actions to perform
Object result = new Result();
return result;
} else {
throw new RuntimeException();
}
}
static boolean isBoolean1() {
return !cond3 && !cond1 && cond2 && cond4;
}
private static boolean isBoolean2() {
return !cond1 && cond2 && cond3;
}
private static boolean isBoolean3() {
return !cond4 && cond3 && cond1 && cond5;
}
static void calculateValues() {}
static class Result {}
}
减少循环复杂度的结果在这里(我使用MetricsReloaded IntelliJ IDEA plugin)。通过分散主要方法和辅助方法之间的复杂性,它确实有效:)
P.S。有趣的事情:我尝试将您的条件提取为局部变量,但它并没有像我最初预期的那样降低方法的复杂性。
我有一段代码在降低圈复杂度方面遇到了问题。由于必须匹配多个条件,我不确定进一步分解它的最佳方法。使事情复杂化的是,在其中两种情况下创建了一个新对象,但在第三种情况下却没有(它调用了另一个方法)。这是伪代码:
if (!cond3 && !cond1 && cond2 && cond4) {
// actions to perform
calculateValues();
return result;
} else if (!cond1 && cond2 && cond3) {
// actions to perform
Object result = new Result();
return result;
} else if (!cond4 && cond3 && cond1 && cond5) {
// actions to perform
Object result = new Result();
return result;
} else {
// throw error because inputs are invalid
}
通过提取方程的公共部分作为新变量,您可以将圈复杂度降低到 11
boolean common = !cond1 && cond2;
...
if (!cond3 && common && cond4) {
// actions to perform
calculateValues();
return result;
} else if (common && cond3) {
// actions to perform
Object result = new Result();
return result;
} else if (!cond4 && cond3 && cond1 && cond5) {
// actions to perform
Object result = new Result();
return result;
} else {
// throw error because inputs are invalid
}
您应该重构该代码,使用方法来抽象那些条件,高圈表示代码需要重构。例如,假设:!cond4 && cond3 && cond1 && cond5
测试登录用户是否有车,那么您应该将该条件组合重构为一个方法:
private boolean loggedUserHasCar() {
return !cond4 && cond3 && cond1 && cond5;
}
对其他条件做同样的事情。 if
带有 4 个条件的语句很难阅读。提取这些语句将降低您的方法圈复杂度并使您的代码更具可读性
我对您的问题很感兴趣,并尝试了较早提出的解决方案,其中提取条件以分离像这样的方法
public class Test {
public static void main(String[] args) {
cyclometricComplexityTest();
}
static boolean cond1 = true;
static boolean cond2 = true;
static boolean cond3 = true;
static boolean cond4 = true;
static boolean cond5 = true;
public static Object cyclometricComplexityTest() {
if (isBoolean1()) {
// actions to perform
Object result = null;
calculateValues();
return result;
} else if (isBoolean2()) {
// actions to perform
Object result = new Result();
return result;
} else if (isBoolean3()) {
// actions to perform
Object result = new Result();
return result;
} else {
throw new RuntimeException();
}
}
static boolean isBoolean1() {
return !cond3 && !cond1 && cond2 && cond4;
}
private static boolean isBoolean2() {
return !cond1 && cond2 && cond3;
}
private static boolean isBoolean3() {
return !cond4 && cond3 && cond1 && cond5;
}
static void calculateValues() {}
static class Result {}
}
减少循环复杂度的结果在这里(我使用MetricsReloaded IntelliJ IDEA plugin)。通过分散主要方法和辅助方法之间的复杂性,它确实有效:)
P.S。有趣的事情:我尝试将您的条件提取为局部变量,但它并没有像我最初预期的那样降低方法的复杂性。