2008-10-15 2 views
18

Недавно наша компания начала измерять циклическую сложность (CC) функций в нашем коде на еженедельной основе и сообщает, какие функции улучшились или ухудшились. Поэтому мы начали уделять гораздо больше внимания ЦК функций.Поиск разъяснений в отношении кода структурирования для уменьшения циклической сложности

Я читал, что CC может быть неофициально рассчитано как 1 + количество точек принятия решения в функции (например, если инструкция, для цикла, выбора и т. Д.), А также количество путей через функцию ...

Я понимаю, что самый простой способом снижения CC является использование метода Extract рефакторинга несколько раз ...

есть нечто Я не уверен, например, что такое CC следующих фрагментов кода?

1)

for (int i = 0; i < 3; i++) 
    Console.WriteLine("Hello"); 

И

Console.WriteLine("Hello"); 
Console.WriteLine("Hello"); 
Console.WriteLine("Hello"); 

Они оба делают то же самое, но первая версия имеет более высокую CC из-за для заявления?

2)

if (condition1) 
    if (condition2) 
     if (condition 3) 
      Console.WriteLine("wibble"); 

И

if (condition1 && condition2 && condition3) 
    Console.WriteLine("wibble"); 

Если предположить, что язык делает оценку короткого замыкания, например, C#, то эти два фрагмента кода имеют тот же эффект, но ... ЦК от первого фрагмента выше, потому что у него есть три решения/если утверждения?

3)

if (condition1) 
{ 
    Console.WriteLine("one"); 

    if (condition2) 
     Console.WriteLine("one and two"); 
} 

И

if (condition3) 
    Console.WriteLine("fizz"); 

if (condition4) 
    Console.WriteLine("buzz"); 

Эти два кода фрагменты делать разные вещи, но они имеют тот же CC? Или вложенные операторы if в первом фрагменте имеют более высокий CC? т. е. вложенные, если высказывания мысленно более сложны для понимания, но это отражено в CC?

ответ

8
  1. Да. В вашем первом примере есть точка принятия решения, а вторая - нет, поэтому первая имеет более высокий CC.
  2. Да, может быть, ваш первый пример имеет несколько точек принятия решений и, следовательно, более высокий CC. (См. Ниже пояснения.)
  3. Да, может быть.Очевидно, что они имеют одинаковое количество точек принятия решений, но есть разные способы расчета CC, что означает ...

... если ваша компания измеряет CC определенным образом, то вам необходимо ознакомиться с этим методом (надеюсь, они используют инструменты для этого). Существуют разные способы вычисления CC для разных ситуаций (операторы case, булевы операторы и т. Д.), Но вы должны получать такую ​​же информацию из метрики независимо от того, какое соглашение вы используете.

Большая проблема заключается в том, что другие упомянули о том, что ваша компания, похоже, больше сосредотачивается на CC, чем на коде, стоящем за ней. В общем, конечно, ниже 5 отлично, ниже 10 хорошо, ниже 20 в порядке, 21-50 должны быть предупреждающим знаком, а выше 50 должны быть большим предупреждающим знаком, но это рекомендации, а не абсолютные правила. Вероятно, вам следует изучить код в процедуре с CC выше 50, чтобы убедиться, что это не просто огромная куча кода, но, возможно, есть определенная причина, почему процедура написана именно так, и это невозможно (для любого количество причин) для реорганизации.

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

4

CC не является панацеей для измерения качества. Ясно, что повторяющийся оператор не «лучше», чем цикл, даже если цикл имеет больший CC. Причина, по которой цикл имеет большее значение CC, заключается в том, что иногда он может выполняться, а иногда и не может, что приводит к двум различным «случаям», которые должны быть протестированы. В вашем случае цикл будет всегда будет выполняться три раза, потому что вы используете константу, но CC недостаточно умна, чтобы обнаружить это.

То же самое с прикованным ifs в примере 2 - эта структура позволяет вам иметь статут, который будет выполнен, если только условие 1 и условие2 истинны. Это особый случай, который невозможен в случае использования & &. Таким образом, if-chain имеет больший потенциал для особых случаев, даже если вы не используете это в своем коде.

6

После просмотра записи в Википедии и на original paper Томаса Дж. МакКейба, кажется, что упомянутые выше предметы являются известными проблемами с метрикой.

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

+0

Чья оригинальный документ вы имеете в виду? Не могли бы вы предоставить ссылку? – RickL 2008-10-15 11:34:24

+0

добавлена ​​ссылка и имя (Thomas J McCabe) – moogs 2008-10-15 11:36:09

+0

Спасибо, я просмотрел бумагу, ее довольно сложно прочитать, поскольку она находится в точном техническом стиле. – RickL 2008-10-15 12:06:31

0

[Off topic] Если вы предпочитаете читаемость по хорошему счету в метриках (был ли это J.Spolsky, который сказал: «что измеряется, сделайте»? - что означает, что метрики злоупотребляют чаще, чем я полагаю), это часто лучше использовать хорошо названный логический, чтобы заменить сложную условную инструкцию.

затем

if (condition1 && condition2 && condition3) 
    Console.WriteLine("wibble"); 

стать

bool/boolean theWeatherIsFine = condition1 && condition2 && condition3; 

if (theWeatherIsFine) 
    Console.WriteLine("wibble"); 
1

Это опасность применения любой метрики вслепую. Метрика CC, безусловно, имеет много достоинств, но, как и любой другой метод улучшения кода, он не может быть оценен в разводе из контекста. Направьте свое руководство на обсуждение Casper Jone по измерению строк кода (я бы мог найти ссылку для вас). Он указывает, что если строки кода являются хорошей мерой производительности, то разработчики ассемблерного языка являются наиболее производительными разработчиками на земле. Конечно, они не более эффективны, чем другие разработчики; он просто требует гораздо больше кода для выполнения того, что говорят языки более высокого уровня, с меньшим количеством исходного кода. Я упоминаю об этом, как я уже сказал, поэтому вы можете показать своим менеджерам, насколько глупым является слепое применение метрик без разумного обзора того, что говорит вам метрика.

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

4

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

Есть две вещи, которые нужно иметь в виду здесь:

  1. достаточно большой код базы: В любом нетривиальной проекте вы будете иметь функции, которые имеют очень высокое значение CC. Настолько высока, что не имеет значения, если в одном из ваших примеров CC будет 2 или 3. Функция с CC, скажем, более 300, определенно что-то анализирует. Не имеет значения, является ли CC 301 или 302.
  2. Не забудьте использовать голову. Существуют методы, которые требуют много точек принятия решений. Часто их можно реорганизовать как-то, чтобы иметь меньше, но иногда они не могут. Не переходите к правилу вроде «Refactor all methods with CC> xy». Посмотрите на них и используйте свой мозг, чтобы решить, что делать.

Мне нравится идея еженедельного анализа. В контроле качества анализ тенденций является очень эффективным инструментом для выявления проблем во время их создания. Это намного лучше, чем ждать до тех пор, пока они не станут настолько большими, чтобы они стали очевидными (см. SPC для некоторых деталей).

1

Цикломатическая сложность аналогична температуре. Они оба являются измерениями, а в большинстве случаев бессмысленными без контекста. Если бы я сказал, что температура снаружи составляла 72 градуса, это не означает многого; но если бы я добавил, что я был на Северном полюсе, число 72 становится значительным. Если кто-то сказал мне, что метод имеет цикломатическую сложность 10, я не могу определить, хорошо это или плохо, без его контекста.

Когда я просматриваю существующее приложение, я нахожу цикломатическую сложность полезной меткой «начальной точки». Первое, что я проверю, это методы с CC> 10. Эти методы «> 10» не обязательно являются плохими. Они просто дают мне отправную точку для просмотра кода.

Общие правила при рассмотрении ряда CC:

  • Отношения между CC# и # испытаний, должны быть CC# < = #tests
  • Refactor для CC# только если оно увеличивает ремонтопригодность
  • CC выше 10 часто указывает один или более Code Smells
0

Я не эксперт по этому вопросу, но я думал, что я дал бы два моих гр энтов. И, возможно, это все, что стоит.

Cyclomatic Complexity, по-видимому, является просто автоматическим ярлыком для поиска потенциально (но не определенно) проблемных фрагментов кода. Но разве реальная проблема не может быть решена одним из испытаний? Сколько тестов требует код? Если CC выше, но количество тестовых примеров одинаково, а код чище, не беспокойтесь о CC.

1.) Там нет места решения. В программе есть один и только один путь, только один возможный результат с любой из двух версий. Первый более краток и лучше, Cyclomatic Complexity будет проклят.

1 тест для обоих

2.) В обоих случаях вы либо писать «Wibble» или нет.

2 тестовых случаев для обоих

3.) Во-первых один может привести к чему, «один» или «один» и «один и два». 3 пути. 2-й не может привести ни к чему, ни к одному из них, ни к обоим. 4 пути.

3 Тестовые для первых 4 тестов для второго

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