2013-03-18 1 views
3

Рассмотрите следующие три функции, которые все ведут себя одинаковым образом, используя другой код для достижения того же самого (примеры написаны на JavaScript, и меня особенно интересуют ответы, применимые к JavaScript , но этот вопрос действительно может применить к любому языку с подобными конструкциями):Cyclomatic сложность логически аналогичного кода

// 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 явно ошибается в этом случае)? Должны ли все три функции выше иметь такую ​​же цикломатическую сложность?

+0

FYI, JSHint теперь сообщает все три из этих функций, чтобы иметь сложность 4. – JLRishe

ответ

7

Cyclomatic complex - количество линейно независимых путей через код. Хотя провал case пуст, я считаю, что это однозначно другой путь. Итак, вопрос в том, вводит ли || новую ветку?

Я просто задумываюсь вслух здесь, но я думаю, что, поскольку JavaScript выполняет оценку короткого замыкания на условных обозначениях, мы действительно получаем две ветви от дизъюнкции. Например, ваша a функция эквивалентна:

function a() { 
    if (x === 0) { 
     return "First"; 
    } else if (x === 1) { 
     return "Second"; 
    } else if (x === 2) { 
     return "Second"; 
    } else { 
     return "Third"; 
    } 
} 

... который имеет 4 филиала, даже если два из них выполняют ту же функцию. (т. е. линейная независимость от ребер, а не вершин). Однако если бы JS не проводила оценку короткого замыкания, я бы склонен рассматривать x === 1 || x === 2, чтобы просто вызвать одну ветвь.

Таким образом, чтобы ответить на ваш вопрос, я думаю, что все три из ваших функций должны иметь один и тот же цикломатической сложности: 4.

+0

+1 , спасибо, я согласен с этим - все три функции должны иметь одинаковую сложность 4. В JSHint определенно исправлены ошибки. Я подожду немного, прежде чем принимать этот ответ, хотя, чтобы поощрять дальнейшие ответы, если есть другие мнения! –

 Смежные вопросы

  • Нет связанных вопросов^_^