Рассмотрим следующие три функции, которые ведут себя одинаково, используя разный код для достижения одной и той же цели (примеры написаны на JavaScript, и меня особенно интересуют ответы применительно к JavaScript, но этот вопрос действительно может относиться к любому язык с похожими конструкциями):
// Random number from 0-9
var x = Math.floor(Math.random() * 10);
// JSHint reports a cyclomatic complexity of 3
function a() {
if (x === 0) {
return "First";
} else if (x === 1 || x === 2) {
return "Second";
}
return "Third";
}
// JSHint reports a cyclomatic complexity of 4
function b() {
switch (x) {
case 0:
return "First";
case 1:
case 2:
return "Second";
default:
return "Third";
}
}
// JSHint reports a cyclomatic complexity of 1
function c() {
return x === 0 ? "First" : x === 1 || x === 2 ? "Second" : "Third";
}
// All three functions return the same value
console.log(a(), b(), c());
Инструмент JSComplexity сообщает, что все три функции имеют сложность 4, что означает, что операторы ||
рассматриваются как независимые ветви, т.е. являются сквозными операторами case
. JSHint, похоже, не заботится об операторе ||
, но точно так же обрабатывает сквозные операторы case
. Кажется, что условный оператор совершенно неверен.
Следует ли при вычислении цикломатической сложности рассматривать сквозные операторы case
и логические операторы «или» как независимые ветви? Как насчет тройных условий (я считаю, что это проще, и JSHint в этом случае явно неверен)? Должны ли все три приведенные выше функции иметь одинаковую цикломатическую сложность?