Какова самая высокая Cyclomatic Complexity любой функции, которую вы поддерживаете? И как бы вы решили провести рефакторинг?
На днях я немного изучал устаревшую систему, которую я поддерживаю, с помощью NDepend (отличный инструмент). Мои выводы почти заставили меня выплеснуть глоток кофе по всему экрану. Лучшие 3 функции в этой системе ранжируются по убыванию цикломатической сложности:
- SomeAspNetGridControl.CreateChildControls(CC из 171 !!!)
- SomeFormControl.AddForm(CC из 94)
- SomeSearchControl.SplitCriteria(CC of 85)
Я имею в виду 171, вау! Разве это не должно быть ниже 20 или что-то? Так что это заставило меня задуматься. Какую самую сложную функцию вы поддерживаете или переделали? И как бы вы занялись рефакторингом такого метода?
Примечание: измеренный CC - это код, а не IL.
Ответы
Ответ 1
Это малыша, по сравнению с 1970-м годами, когда я работал с несколькими лет назад. Мы использовали оригинальный инструмент McCabe для графического отображения CC для некоторого кода. Распечатка была чистой, потому что линии, показывающие функциональные пути, были настолько плотно упакованы и спагетти-подобны. У меня нет цифры, но она должна быть выше 171.
Что делать
Per Код завершен (первое издание):
Если оценка:
- 0-5 - процедура, вероятно, прекрасна.
- 6-10 - начните думать о способах упрощения процедуры
- 10+ - перерыв части подпрограммы во вторую процедуру и вызов ее из первой процедуры
Может быть хорошей идеей написать модульные тесты при распаковке исходной процедуры.
Ответ 2
Это для кода C/С++, который в настоящее время поставляется в продукте:
самое высокое значение CC, которое я мог бы достоверно идентифицировать (т.е. я не подозреваю, что инструмент ошибочно добавляет значения сложности для несвязанных экземпляров main (...)):
- функция обработки изображений: 184
- загрузчик элементов базы данных с проверкой: 159
Существует также тестовая подпрограмма с CC = 339, но это не является строго частью продукта доставки. Заставляет меня задаться вопросом, как можно реально проверить тестовые примеры, реализованные там...
и да, имена функций были подавлены для защиты виновных:)
Как изменить его:
Уже устранены проблемы, связанные с этим. Проблемы в основном вызваны двумя причинами:
- код спагетти (без инкапсуляции, много копий)
- код, предоставленный группе продуктов некоторыми учеными без реальной разработки программного обеспечения/инженерии/плотницких работ.
Основным методом является идентификация связных частей спагетти (натяжение нити:)) и разбиение функций looooong на более короткие. Часто есть сопоставления или преобразования, которые можно извлечь в функцию или вспомогательный класс/объект. Переход на использование STL вместо ручных контейнеров и итераторов может также сократить много кода. Использование std::string вместо C-строк помогает много.
Ответ 3
Я нашел другое мнение по этому поводу в этой записи блога, которая, кажется, имеет смысл и работает для меня, сравнивая ее с различными базами кода. Я знаю, что это очень самоуверенная тема, поэтому YMMV.
- 1-10 - просто, не так много рисков
- 11-20 - сложный, низкий риск
- 21-50 - слишком сложный, средний риск, внимание
- Более 50 - слишком сложно, не могу проверить, высокий риск