[英]Improve the cyclomatic complexity code for if-else statements
我在遇到循环复杂性问题的方法中有一块if-else语句。 我尝试为此使用switch语句,但问题仍然存在。
if (fileName.startsWith(HwErrorsEtlConstants.MR_RAW_GRADIENT_ERRORS)) {
method1()...
} else if (fileName.startsWith(HwErrorsEtlConstants.MR_RAW_PFEI_ERRORS)) {
method2()...
} else if (fileName.startsWith(HwErrorsEtlConstants.MR_RAW_RFAMP_ERRORS)) {
method3()...
} and so on...
public static void method1(IOutputWriter writer, String fileName, InputStream fileInputStream) throws IOException {
//logic for the method
}
编辑 :如前所述,您已经检查了可以抛出的Exception
和方法中的参数。 由于Runnable
并未声明它会引发Exceptions
并且也不接受您必须创建自己的FunctionalInterface
任何参数(请单击此处查看其真正含义):
public interface ThrowingRunnable {
void run(IOutputWriter writer, String fileName, InputStream fileInputStream) throws IOException;
}
然后,只需在下面我先前建议的代码中用ThrowingRunnable
替换Runnable
,就可以了。
您可以创建HwErrorsEtlConstants
到特定方法的映射(使用Java 8):
static final Map<String, Runnable> MAPPING;
static {
Map<String, Runnable> temp = new HashMap<>();
temp.put(HwErrorsEtlConstants.MR_RAW_GRADIENT_ERRORS, this::method1);
temp.put(HwErrorsEtlConstants.MR_RAW_PFEI_ERRORS, this::method2);
temp.put(HwErrorsEtlConstants.MR_RAW_RFAMP_ERRORS, this::method3);
MAPPING = Collections.unmodifiableMap(temp);
}
然后,在您的方法中,可以使用Java 8中也引入的Stream
:
// Optional indicates a potentially absent value, it's just a wrapper around a Runnable
Optional<Runnable> optional = MAPPING
// create a Stream from the entries
.entrySet().stream()
// keep the items that match the condition and drop every other
.filter(e -> filename.startsWith(e.getKey()))
// we had Map.Entry<String, Runnable>, but now we only need the value e.g. the Runnable
.map(Map.Entry::getValue)
// short circuit, e.g. we only want the first value that matches
.findFirst();
// checks if anything is present, this is used as the MAPPING "could" be empty
if(optional.isPresent()) {
// unpack the value and call it with arguments
optional.get().run(aWriter, someFileName, anInputStream);
} else {
// nothing matched, throw error or log etc.
}
尽管如上所述,您当前的解决方案确实不错,但是我想您正在使用Sonar进行代码分析。 有时,Sonar只会产生误报,因此您也可以放心地忽略它们。
进一步阅读以帮助您了解Java 8:
圈复杂度是一个问题:确实是循环 。
然后使用if / switch(不是面向对象的)在属性上拆分流。 它还可能违反关注点分离 :拥有许多处理完全不同的较小方面的方法。
如果字段数较大,并且行数较大,请考虑提取处理一个方面的类。
为了降低循环复杂性,请检查以控制调用者的流程,同一呼叫的重复,实用的重复代码。 然后尝试(重新)移动循环。 最好的是可以将各个周期放在一起。 并处理列表/集合/流。
您可以使用谓词和函数功能接口通过Java 8方法解决此问题。 您必须通过谓词放置所有条件,并且在Function中,可以添加条件匹配时需要执行的实现。
Map<Predicate,Function<String,String>> map = new HashMap<>();
Predicate<String> p = (fileName)->fileName.startsWith(HwErrorsEtlConstants.MR_RAW_GRADIENT_ERRORS);
Function<String,String> method = (input)->{ return "output";};
map.put(p,method);
Optional<String> result =
map.entrySet()
.stream()
.filter(entry->entry.getKey().test(fileName))
.map(entry->entry.getValue().apply())
.findFirst();
要么
map.entrySet()
.stream()
.filter(entry->entry.getKey().test(fileName))
.forEach(entry->entry.getValue().apply());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.