Что означает «цикломатическая сложность» моего кода?

42

Я новичок в статическом анализе кода. Мое приложение имеет Cyclomatic сложность 17 754. Само приложение имеет всего 37 672 строки кода. Можно ли сказать, что сложность высока в зависимости от строк кода? Что именно говорит мне Cyclomatic сложность?

Злые птицы
источник
Это полностью зависит от того, что вы делаете. Если вы пытаетесь сделать что-то простое, то оно очень, очень высокое. Например, у вас не должно быть такого соотношения в «привет мире».
cwallenpoole

Ответы:

48

Что именно говорит мне Cyclomatic сложность?

Цикломатическая сложность - это не мера строк кода, а количество независимых путей через модуль. Ваша цикломатическая сложность 17 754 означает, что ваше приложение имеет 17 754 уникальных пути через него. Это имеет несколько последствий, как правило, с точки зрения сложности понимания и тестирования вашего приложения. Например, цикломатическая сложность - это количество тестовых случаев, необходимых для достижения 100% покрытия ветвлений, при условии хорошо написанных тестов.

Хорошей отправной точкой может стать статья в Википедии о цикломатической сложности . В нем есть несколько фрагментов псевдокода и несколько графиков, которые показывают, что такое цикломатическая сложность. Если вы хотите узнать больше, вы также можете прочитать статью МакКейба, где он определил цикломатическую сложность .

Мое приложение имеет Cyclomatic сложность 17 754 строк кода. Само приложение имеет всего 37 672 строки кода. Можно ли сказать, что сложность высока в зависимости от строк кода?

Не за что. Приложение с несколькими строками кода и большим количеством условных выражений, вложенных в циклы, может иметь чрезвычайно высокую цикломатическую сложность. С другой стороны, приложение с несколькими условиями может иметь низкую цикломатическую сложность. Это слишком сильно упрощает, но я думаю, что это передает идею.

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

Томас Оуэнс
источник
36

Цикломатическая сложность - это способ определения необходимости рефакторинга вашего кода. Код анализируется и определяется число сложности. Сложность определяется путем ветвления (если операторы и т. Д.) Сложность также может принимать во внимание вложенность циклов и т. Д. И другие факторы в зависимости от используемого алгоритма.

Число полезно на уровне метода. На более высоких уровнях это просто число.

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

Развертывание до уровня сложности класса и метода определит области кода, которые должны быть преобразованы в более мелкие методы или переработаны, чтобы устранить сложность.

Рассмотрим CASEутверждение с 50 случаями в одном методе. Возможно, у каждого государства своя бизнес-логика. Это создаст цикломатическую сложность 50. Есть 50 точек принятия решения. Оператор CASE может быть изменен с использованием фабричного шаблона, чтобы избавиться от логики ветвления. Иногда вы можете выполнить рефакторинг (разбить метод на более мелкие части), а в некоторых случаях только редизайн уменьшит сложность.

В общем, для сложности уровня метода:

  • <10 Легко поддерживать
  • 11-20 труднее поддерживать
  • 21+ кандидатов на рефакторинг / редизайн

Также учтите, что более высокие сложности делают код сложнее для модульного тестирования.

Самая высокая сложность, которую я видел в одном методе, была 560. Это было около 2000 строк операторов if в одном методе. В основном не поддерживаемый, непроверяемый, полный потенциальных ошибок. Представьте себе все случаи модульного тестирования, необходимые для этой логики ветвления! Не хорошо.

Старайтесь, чтобы все методы не превышали 20, и понимайте, что стоит реорганизовать любой метод, чтобы сделать его менее сложным.

Джон Рейнор
источник
Это лучший ответ.
Pacerier
2
@Pacerier В этом случае просто добавьте ответ;).
Zero3
> «В общем, для уровня сложности метода» Цитирование?
Бенни Боттема
Одним из оригинальных приложений McCabe было ограничение сложности процедур при разработке программ; он порекомендовал программистам учитывать сложность модулей, которые они разрабатывают, и разбивать их на более мелкие модули всякий раз, когда цикломатическая сложность модуля превышала 10.
Джон Рейнор
«Оператор CASE, возможно, придется изменить, используя фабричный шаблон, чтобы избавиться от логики ветвления». Зачем? Это не устраняет сложности логики; он просто скрывает это и делает его менее заметным, и, следовательно, более сложным в обслуживании.
Мейсон Уилер
1

Это количество различных путей в вашем приложении. Проверьте эту статью IBM на CC .

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

Что я лично читал много раз, так это то, что методы с СС выше 10 имеют более высокий риск дефектов.

Я использую Sonar для проверки качества кода моих приложений и, по-моему, выдает предупреждение, если у вас есть методы с +10 CC. Тем не менее, это может ничего не значить. Один конкретный пример: если вы используете Eclipse для генерации equalsметода, основанного на свойствах вашего компонента, CC очень быстро поднимется над крышей ...

Jalayn
источник
1
По умолчанию PMD также предупреждает о цикломической сложности 10. Анализ сложности на уровне отдельных методов также позволяет игнорировать методы, которые могут иметь веские причины для высокой CC, например сгенерированные equalsметоды.
Томас Оуэнс
Я не был уверен, поэтому я проверил, но Сонар внутренне использует PMD, чтобы получить эту меру. Так что все это имеет смысл :-)
Джалайн
-1

Это зависит от того, какой инструмент вы использовали. Некоторые из инструментов с открытым исходным кодом принимают класс как модуль или другой уровень структуры как модуль. Следовательно, чем больше проект получает, тем выше его циклическая сложность. Однако, для моего личного понимания, это должно быть на функциональной основе. Поскольку чем больше проект становится, тем больше функций он посещает.

Я рекомендую вам использовать инструмент под названием Lizard, и вы можете найти код ресурса и скачать zip-файл на github. Он также имеет онлайн-версию, если в вашем коде мало конфиденциальной информации.

Значимый CCN, о котором вы должны заботиться, находится на функциональной основе, отличной от любой другой. Кроме того, держите CCN Unber 15 каждой функции будет идеальным диапазоном.

Цзяхан Ли
источник