Что такое цикломатическая сложность?

Термин, который я вижу время от времени - "Цикломатическая сложность". Здесь, на SO, я видел несколько Вопросов о том, "как рассчитать CC языка X" или "Как мне сделать Y с минимальным количеством CC", но я не уверен, что действительно понимаю, что это такое.

На веб-сайте NDepend я увидел объяснение, которое в основном гласит: "Количество решений в методе. Каждое, если, для && и т. Д. Добавляет +1 к" счету "CC". Это действительно так? Если да, то почему это плохо? Я вижу, что можно хотеть сохранить довольно малое количество операторов if, чтобы облегчить понимание кода, но действительно ли это все?

Или есть какая-то более глубокая концепция?

14 ответов

Решение

Я не знаю более глубокой концепции. Я считаю, что это обычно рассматривается в контексте индекса ремонтопригодности. Чем больше разветвлений в конкретном методе, тем сложнее поддерживать ментальную модель работы этого метода (в целом).

Методы с более высокой цикломатической сложностью также сложнее получить полное покрытие кода в модульных тестах. (Спасибо Marc W!)

Это приносит все другие аспекты ремонтопригодности, конечно. Вероятность ошибок / регрессий / пр. Основная концепция довольно проста, хотя.

Цикломатическая сложность измеряет количество раз, которое вы должны выполнить блок кода с различными параметрами, чтобы выполнить каждый путь через этот блок. Чем выше счет, тем хуже, поскольку он увеличивает вероятность логических ошибок, выходящих из вашей стратегии тестирования.

Cyclocmatic complexity = Number of decision points + 1

Точки принятия решения могут быть вашими условными утверждениями, такими как if, if … else, switch, for loop, while loop и т. Д.

В следующей таблице описывается тип приложения.

  • Цикломатическая Сложность лежит 1 - 10  Считается нормальным приложением

  • Цикломатическая Сложность лежит 11 - 20 application Умеренное применение

  • Цикломатическая Сложность лежит 21 - 50  Рискованное применение

  • Цикломатическая сложность лежит более 50  Нестабильное применение

Википедия может быть вашим другом по этому вопросу: определение цикломатической сложности

По сути, вы должны представить свою программу в виде графика потока управления, а затем

Сложность (...) определяется как:

M = E − N + 2P

где

  • М = цикломатическая сложность,
  • E = количество ребер графа
  • N = количество узлов графа
  • P = количество подключенных компонентов

CC - это концепция, которая пытается понять, насколько сложна ваша программа и насколько сложно ее протестировать одним целым числом.

Да, это действительно так. Чем больше путей выполнения может пройти ваш код, тем больше вещей нужно протестировать, и тем выше вероятность ошибки.

Еще один интересный момент, который я слышал:

Места в вашем коде с самыми большими отступами должны иметь самый высокий CC. Как правило, это наиболее важные области для обеспечения охвата тестирования, поскольку ожидается, что их будет сложнее читать / поддерживать. Как отмечают другие ответы, это также более сложные области кода для обеспечения покрытия.

Cyclomatic Complexity действительно просто страшное модное слово. Фактически, это мера сложности кода, используемая при разработке программного обеспечения, чтобы указать на более сложные части кода (более вероятно, что они будут содержать ошибки, и поэтому должны быть очень тщательно и тщательно протестированы). Вы можете рассчитать его, используя формулу E-N+2P, но я бы посоветовал вам рассчитать это автоматически с помощью плагина. Я слышал эмпирическое правило, что вы должны стремиться держать CC ниже 5, чтобы поддерживать хорошую читабельность и удобство сопровождения вашего кода.

Я только недавно экспериментировал с плагином Eclipse Metrics над моими проектами Java, и у него есть действительно хороший и лаконичный файл справки, который, конечно, будет интегрирован с вашей обычной справкой Eclipse, и вы можете прочитать некоторые определения различных мер сложности, а также советы и рекомендации на улучшение вашего кода.

Цикломатическая сложность вычисляется с использованием графа потока управления. Число количественных показателей линейно независимых путей через исходный код программы называется Cyclomatic Complexity ( if/ if else / for / while)

Каждая точка принятия решения в подпрограмме (цикл, переключение, если и т. Д.) По существу сводится к эквивалентному оператору if. Для каждого if у вас есть 2 кодовых пути, которые можно взять. Итак, с 1-й ветвью есть 2 кодовых пути, со второй - 4 возможных пути, с 3-й - 8 и так далее. Существует не менее 2**N кодовых путей, где N - количество ветвей.

Это затрудняет понимание поведения кода и его тестирование, когда N выходит за пределы небольшого числа.

В ответах, предоставленных до сих пор, не упоминается соотношение качества программного обеспечения и цикломатической сложности. Исследования показали, что более низкий показатель цикломатической сложности должен помочь в разработке программного обеспечения более высокого качества. Это может помочь с такими качественными характеристиками программного обеспечения, как удобочитаемость, удобство обслуживания и портативность В общем случае следует попытаться получить показатель цикломатической сложности от 5 до 10.

Одна из причин использования таких метрик, как цикломатическая сложность, заключается в том, что в целом человек может одновременно отслеживать только около 7 (плюс или минус 2) фрагментов информации в вашем мозгу. Поэтому, если ваше программное обеспечение слишком сложное с несколькими путями принятия решений, маловероятно, что вы сможете визуализировать, как будет вести себя ваше программное обеспечение (т. Е. Оно будет иметь высокий показатель цикломатической сложности). Это, скорее всего, приведет к разработке ошибочного или ошибочного программного обеспечения. Более подробную информацию об этом можно найти здесь, а также в Википедии.

Вот и все, идея в том, что метод с низким CC имеет меньше разветвлений, циклов и т. Д., Что делает метод более сложным. Представьте, что вы просматриваете 500 000 строк кода с помощью анализатора и видите пару методов, которые имеют на порядок более высокий уровень CC. Это позволяет вам затем сосредоточиться на рефакторинге этих методов для лучшего понимания (также часто бывает, что высокий CC имеет высокую частоту ошибок)

Рассмотрим график потока управления вашей функции с дополнительным ребром, бегущим от выхода к входу. Цикломатическая сложность - это максимальное количество разрезов, которое мы можем сделать, не разделяя график на две части.

Например:

function F:
    if condition1:
       ...
    else:
       ...
    if condition2:
       ...
    else:
       ...

График потока управления

График потока управления

Вы, вероятно, можете интуитивно понять, почему связанный граф имеет цикломатическую сложность 3.

Вот так. Однако каждая ветвь оператора "case" или "switch" имеет тенденцию считаться как 1. По сути, это означает, что CC ненавидит операторы case и любой код, который требует их (процессоры команд, конечные автоматы и т. Д.).

Цикломатрическая сложность - это, в основном, показатель для определения областей кода, которые требуют большего внимания для удобства обслуживания. Это будет в основном вклад в рефакторинг. Это определенно указывает на область улучшения кода с точки зрения избежания глубокого вложенного цикла, условий и т. Д.

Цикломатрическая сложность - это мера того, насколько сложна единица программного обеспечения. Она измеряет количество различных путей, по которым программа может следовать с условными логическими конструкциями (если,while,for,switch & case и т. Д....). Если вы хотите узнать больше о его расчете, вот отличное видео на YouTube, которое вы можете посмотреть https://www.youtube.com/watch?v=PlCGomvu-NM

Это важно при разработке тестовых случаев, поскольку в нем раскрываются различные пути или сценарии, которые может использовать программа. "Чтобы иметь хорошую тестируемость и ремонтопригодность, McCabe рекомендует, чтобы ни один программный модуль не превышал цикломатическую сложность 10"(Marsic,2012, p. 232).

Ссылка: Marsic., I. (2012, сентябрь). Программная инженерия. Университет Рутгерса. Получено с www.ece.rutgers.edu/~marsic/books/SE/book-SE_marsic.pdf

Другие вопросы по тегам