测量环形复杂性

时间:2016-10-30 06:25:37

标签: java cyclomatic-complexity

下面的代码以{Package1:Dependency,Package2:Dependency}格式接收包名称和依赖项的数组,并将它们放入要返回的hashmap中。根据我的采访者的说法,该方法的圈复杂度为12,这太高了,无法接受。但是,我已经在代码上运行了指标,报告的复杂性实际上是2.

有人能告诉我为什么复杂性如此之高以及如何简化它以降低圈复杂度?我在这里不知所措。

public static HashMap<String, String> parseDependencies(String[] args) {
    HashMap<String, String> pairs = new HashMap<String, String>();
    for (int i = 0; i < args.length; i++) {
        if (!args[i].contains(": ") || args[i].startsWith(": ")) {
            logger.log(Level.WARNING, ENTRY + args[i] + FORMATTING);
            continue;
        }
        String[] entry = args[i].split(": ");
        if (entry.length < 2) {
            pairs.put(entry[0], null);
        } else {
            pairs.put(entry[0], entry[1]);
        }
    }
    return pairs;
}

2 个答案:

答案 0 :(得分:1)

不同的工具稍微不同地计算圈复杂度。我不知道面试是如何到达12的。或者你是如何到达的2.粗略地说,圈复杂度计算条件,循环和控制流语句的数量。你有一个循环,3个条件,一个continueelsereturn,它给出7,看起来是正确的。

实施并没有让我觉得“复杂”,但是它有很多问题:

  • 返回类型应为界面,Map<String, String>而不是HashMap
  • 应该使用for-each循环而不是计数循环
  • 如果向entry.length添加第二个参数-1,则可以消除split上的条件。这样,由于args[i].contains(": ")continue之前的条件,entry.length将保证至少为2。
  • 重复:并不是很好。

在这个特定的例子中,我会更多地担心这些事情而不是圈复杂度。

最后,减少圈复杂度的常用技术是将代码提取到辅助方法。例如,复杂的布尔条件,甚至整个循环体。

答案 1 :(得分:0)

首先,令人惊讶的是,面试官依靠Cyclomatic Complexity来衡量在面试中编写的代码。我不认为我想在一家经常做那种事情的“商店”工作。

但是,从CC角度来看,您的代码可以变得更简单:

public static HashMap<String, String> parseDependencies(String[] args) {
    HashMap<String, String> pairs = new HashMap<String, String>();
    for (int i = 0; i < args.length; i++) {
        String[] entry = args[i].split(": ");
        if (entry.length != 2 || entry[0].isEmpty()) {
           logger.log(Level.WARNING, ENTRY + args[i] + FORMATTING);
        } else if (entry[1].isEmpty()) {
            pairs.put(entry[0], null);
        } else {
            pairs.put(entry[0], entry[1]);
        }
    }
    return pairs;
}

逻辑和控制流路径已经简化,应该减少CC测量。

(我也借此机会纠正了一些明显的错误。)