Благодаря вопросу в Code Review у меня возникло небольшое разногласие (которое, по сути, является возможностью чему-то научиться) о том, что именно является Cyclomatic Complexity для приведенного ниже кода.
public static void main(String[] args) {
try {
thro();
thro();
thro();
thro();
thro();
thro();
thro();
}
catch (NullPointerException e) {
}
}
private static Random random = new Random();
public static void thro() throws NullPointerException {
if (random.nextBoolean())
throw new NullPointerException();
System.out.println("No crash this time");
}
При написании этого кода в Eclipse и использовании плагина метрик Eclipse он говорит мне, что цикломатическая сложность McCabe для основного метода равна 2, а для thro
метода - 2.
Однако кто-то еще говорит мне, что сложность вызова thro
несколько раз равна number of calls * method complexity
, и поэтому утверждает, что сложность основного метода равна 7 * 2 = 14.
Мы измеряем разные вещи? Можем ли мы оба быть правильными? Или какова здесь настоящая цикломатическая сложность?
metrics
cyclomatic-complexity
Саймон Форсберг
источник
источник
Ответы:
Когда я правильно понял это, Cyclomatic Complexity of
main
is 8 - это число линейно независимых путей в коде. Вы либо получаете исключение в одной из семи строк, либо ни в одной, но не более чем в одну. Каждая из этих возможных «точек исключения» в точности соответствует одному другому пути в коде.Я предполагаю, что когда МакКейб изобрел этот показатель, у него не было языков программирования с учетом обработки исключений.
источник
main
метода?Будучи «другим парнем», я отвечу здесь и буду точен в отношении того, что я говорю (что я не особенно точно описал в других формулах).
Используя приведенный выше пример кода, я вычисляю цикломатическую сложность как 8, и у меня есть комментарии в коде, чтобы показать, как я это вычисляю. Для описания пути я буду считать успешную проходной все те
thro()
вызовы , как «основным» «кодом путь» (или «CP = 1»):Итак, я считаю 8 путей кода в этом основном методе, который для меня является цикломатической сложностью 8.
С точки зрения Java, каждый механизм выхода из функции имеет значение для его сложности, поэтому метод, имеющий состояние успеха и, например, выбрасывающий, возможно, до 3 исключений, имеет 4 документированных пути выхода.
Сложность метода, вызывающего такую функцию, такова:
Я думаю, что нужно учитывать и то, что, по моему мнению,
catch
предложение не вносит вклад в сложность метода,catch
является просто цельюthrows
ветви, и, таким образом, блок перехвата, который является целью несколькихthrow
подсчетов s 1 раз для каждогоthrow
, а не только один раз для всего.источник
catch (Throwable t) {...
то я догадываюсь, что не имеет значения, сколько исключений он объявляет.