Пригодится разработчикам, которые заботяться о качестве своего продукта, простоте его тестирования и дальнейшей поддержке.
Если у вас есть опыт разработки информационных систем, вы наверняка знаете, что со временем (а иногда и сразу) написанный код усложняется и увеличивается в размере. Это приводит к тому, что становится сложно предсказать, к каким последствиям может привести модификация кода, а количество тестов, которые нужно провести, растет экспоненциально с ростом количества циклов и условий.
Иногда встречаются рекомендации по написанию вроде «старайтесь, что бы тексты ваших методов не превышали размера экрана». Очевидно, что это несерьезное требование, тем более, что в профессиональном мире давно уже существуют метрики на сложность кода. Одна из таких метрик — цикломатическая сложность. Что это и как она рассчитывается — можно почитать в википедии (статья на английском написана лучше).
Данный инструмент предназначен для расчета цикломатической сложности любого участка кода — фрагмент модуля, отдельного метода, целого модуля или набора модулей. Все менеджеры знают, что управлять чем-то возможно только тогда, когда это можно измерить. На мой взгляд, использование такой метрики сложности кода, как цикломатическая сложность, отлично подходит для выявления проблемых мест конфигурации, нахождения точек, которые требуют реинжиниринга. А данный инструмент поможет вам в этом.
Как использовать данный инструмент:
- Открыть обработку в 1С:Предприятии 8.
- Вставить фрагмент кода, который вы хотите проанализировать в поле на закладке «Текст»
или выбрать каталог, в котором лежат искодные коды модулей (в текстовом виде), указав маску выбора фалов
или выбрать файл с текстом исходного кода. - Нажать на кнопку «Выполнить».
- Полученные результаты можно отсортировать по любой из колонок дерева результатов. Для наглядности, отдельные методы в дереве результатов подкрашиваются в цвет, символизирующий его сложность.
- На закладке «Настройки» можно поменять цвета, настройки градиента раскрашивания.
Как применять это в реальной жизни?
В комментариях попросили рассказать, как это применять в реальной жизни. Делюсь своими рекомендациями, основанными на внедрении этого инструмента в нашем коллективе:
- Оптимум метрики: не стОит вводить. Мы ограничились введением верхнего допустимого значения. Исследования, о которых говорится в википедии в разделе «Применение», рекомендуют ограничивать сложность на уровне 10. В отдельных случая можно допустить поднятие лимита до 15. Сложность более 50 гарантирует вам головную боль при поддержке.
Учитывая специфику разработки ИС (мало математически строгих алгоритмов — всегда нужны какие-то исключения и допущения), мы подняли допустимую верхнюю границу сложности до 14. В отдельных случаях, допускается превышение до 20 с обязательным комментарием в коде метода, чем вызвана необходимость повышенной сложности. - Разработчик, при передаче задачи в тест, самостоятельно замеряет сложность кода который он произвел/модифицировал. При необходимости, некоторые части выносятся в отдельные методы. В ряде случаем это также увеличивает или облегчает повторное использование кода.
- Для разработчиков, которые систематически превышают максимально допустимую сложность кода, можно применять штрафные санкции.
- Кстати, не стоит брать типовые конфигурации в качестве ориентира по сложности кода. Самое высокое значение цикломатической сложности, которое я видел, было около 350. И да, это был типовой регламентированный отчет.
Примечания по использованию:
- Поддерживается анализ кода написанного как на русском, так и на английском языке.
- Обработка работает в обычном (не управляемом) приложении, но исходный код может анализировать как для обычного, так и для управляемого приложения. Если вам нужна версия обработки для работы под управляемым приложением — пишите в комментариях или в личку.
- Вы можете использовать обработку по своему усмотрению в рамках действующего законодательства вашего государства. Единственная просьба: если у вас есть замечания или предложения по улучшению обработки, а также в случае нахождения багов — пишите мне об этом в комментариях или мне в личку.
(0) Автор, объясните хотя бы в двух словах, чем полезна ваша обработка на практике? Какие выводы можно сделать, вычислив ЦСП?
И какое значение должно быть для нормального кода… может статистику по типовым собирали или ещё что. С чем сравнивать?
я тоже не совсем понял как это работает, но за труды +
(1) hulio, (2) comol, коллеги, по вашим просьбам добавил описание практического применения.
вычисление ЦС дает ответ на вопрос, нужно ли уже разбить код на несколько методов, или еще нет.
(4) Spitfire, Вот теперь однозначно «+» и мой грейт респект.
Спасибо, нужная штука!
Спасибо, респект!
Эх, еще бы такое в снегопат.
(7) boggonzikov,
(8) pumbaE, перебрать все модули конфигурации можно через Конфигуратор-Выгрузить файлы конфигурации.
Насчет сводного отчета — конкретизируйте, пожалуйста, как вы это видите. Возможно, я добавлю в саму обработку какие-то более удобные инструменты анализа результатов анализа =)
На мой взгляд, нужно прямо в тексте статьи сказать, что данная метрика является просто суммой количества слов «Тогда» (then), «?(» и «Цикл» (loop) в тексте модуля (не находящихся в комментариях или кавычках). Иначе термин «цикломатическая сложность» заставляет представлять что-то чрезвычайно хитроумное. Ничего плохого в простоте метрики нет. Однако такое более понятное определение поставит ее в ряд с другими простыми метриками типа количества строк, букв, слов, разделителей «;» в одной процедуре (функции) модуля.
(10) ildarovich, можно хоть весь листинг привести в описании. Зачем?
И потом, обработка действительно считает цикломатическую сложость — количество циклов в графе управления программы. Если бы 1С была другой, например, многопоточной, такой простой реализации не получилось бы.
И мне бы не хотелось, что бы эта метрика оказалась в одном ряду с подсчетом количества слов или строк метода. Почему? Потому что эти метрики на практике бесполезны, и интересуют только любителей больших чисел.
Интересная штука.
ОФФ: Странно, но в рассылке по почте стоит автором tormozit.
(9) Spitfire, мое программировать — это в плане добавить в снегопате обход дерева метаданных и передачу текстов в вашу обработку, т.е. что бы не было необходимости нажимать выгрузить тексты модулей, потом запускать обработку и т.д., а нажал волшебную кнопку и сразу автоматом заработало.
Имхо, для ежедневного использования непригодна, нет признаков игнорировать какой-то модуль; допустим типовая конфигурация, я все равно ничего не буду делать если вдруг ваша обработка покажет n, нет m число (m больше выглядит чем n). Т.е. сказать, а что изменилось за неделю получить такую информацию трудно.
Тот же итоговый отчет необходимо строить только по граничным показателям, если у меня макс. стоит число 15, то зачем мне для одного из вариантов отчета видеть процедуры с 1 или 2?
(13) Я тут не причем =)
Однако замечал во многих рассылках о комментариях с инфостарта, что я там как автор указан. Возможно кто первый подписался на комментарии, того рассылка и считает автором?
(12) Если быть занудой, то
обработка НЕ считает. Собственно, в приведенных Вами ссылках все это уже написано. В частности, и то, что основное назначение метрики — это оценка мощности множества тестов для процедуры или функции. При этом делается ПРЕДПОЛОЖЕНИЕ, что мощность теста определяется необходимостью прогона графа управления по всем возможным путям. На практике при программировании в 1С редко когда применяется (автоматическое) модульное тестирование или юнит-тестирование. Поэтому применение данной метрики — это определенная условность. И доказать, что эта метрика лучше, чем, например, число строк в модуле, невозможно из-за трудностей определения критерия сравнения.
— думаю, что это высказывание просто голословно.
(13) pumbaE, если честно, я не думал о потребности анализировать изменения за определенный период. мы у себя ее используем не так. Я подумаю о внедрении такой функциональности и о внедрении отборов в дерево результатов.
(15) ildarovich, указанные вами предположения сделаны не мной, а множеством умных людей, занимающимися computer science. Аналогичные предположения делаются, когда производится любое автоматизированное тестирование — регрессионное, юнит, модульное, любое — ведь протестировать все случаи, с которыми придется столкнуться программе, невозомжно и ненужно. Потому каждый сам выбирает себе достаточное множество тестов. А эта метрика, как вы правильно сказали, помогает оценить мощность множества таких тестов. И, кстати, то, что среди разработчиков на 1С автоматическое тестирование применяется реже, чем в других технологиях, не делает нам чести. К счастью, ситуация улучшается, я могу это видеть.
количество циклов в графе управления программы
обработка НЕ считает.
Это равносильно утверждению, что половина произведения катетов прямоугольного треугольника не дает нам его площади. А дает лишь.. хм.. половину произведения катетов.
К сожалению, эта метрика придумана не мной, потому я не буду здесь ее защищать. Ее полезность изучена и доказана.
— думаю, что это высказывание просто голословно.
в таком случае, приведите, пожалуйста, практическую ценность для разработчика числа строк или символов модуля. И объясните, что буду означать изменения этих метрик при добавлении/удалении больших комментариев или запросов.
Очень интересная разработка. Очень порадовала фраза:
О чём говорят эти замеры? На сколько я понял, главное, о чём говорит нам числовой показатель — «количество» учитываемых условий/условностей в каком-либо методе. Причём, если следовать рекомендациям, то эти учитываемые условия следует минимизировать, вынося их просчёт в отдельные процедуры и функции.
Забавно, что в типовых конфигурациях самыми «сложными» оказались те, что отвечают за:
1) вывод печатных (ПечатьСчетаФактуры1137 — 39) и регламентированной отчётности (ПроверитьВозможностьВыгрузки — 131),
2) процедуры проведения документов по регистрам.
Хотя мне кажется, что если на одном уровне встречается «Если… Тогда… КонецЕсли», а за ним следует снова «Если… Тогда… КонецЕсли», то это не усложнят код (условия не вложены, на одном уровне), а на числовой показатель влияют: +1 за каждое Если… Тогда… КонецЕсли. Ибо эти проверялки условий — необходимость, которую выносить в отдельные функции вряд ли стоит. Посмотрите функции «ПроверитьВозможностьВыгрузки» в регламентированных отчётах.
По сему такая мысль: а может не надо при следующими друг за другом «Если… Тогда… КонецЕсли» на одном уровне увеличивать счётчик на +1? А вот за вложенность можно увеличивать. Чем больше вложенностей условий, тем запутаннее код. Тоже самое касается и циклов. Но у них другая беда — много циклов гораздо хуже, чем тоже количество «Если…».
Однако, метод есть метод. Он лишь ориентирует на ВОЗМОЖНО проблемные места, а не является показателем проблемности. То есть условие необходимое, но не достаточное.
(18) Qsko, ну еще в зарплатах модулях очень любят использовать, для возможности группировки.
(возможно потому, что у разрабов типовых снегопата нет 🙂 )
Интересно! Респект!
(21) Могу также добавить, что существует по крайней мере четыре приема, позволяющие намеренно занижать цикломатическую сложность, считаемую Вашей обработкой:
1) «Раскрытие циклов» — повторение одинаковых строк в программе, если число повторений заранее известно;
2) Использование оператора «Выполнить» — кавычки будут экранировать Тогда и Цикл от подсчета;
3) Использование списка (или таблицы) значений и поиска в нем вместо Если … ИначеЕсли … ИначеЕсли … КонецЕсли;
4) Использование рекурсии вместо циклов. При этом вместо условия выхода использовать неполноту вычисления логических выражений (не вполне уверен, но стоит попробовать).
(11) Если привести в статье более понятное определение, то разработчики, желающие разрабатывать код со значением сложности менее 10, будут просто складывать число циклов и условных операторов (считать до 10 не сложно) вместо более «цикломатически-сложной» (шутка) процедуры запуска обработки.
Тем не менее статью считаю полезной, поставил плюс, метрику возьму на вооружение. Ну и ради спортивного интереса код в обработке нужно попытаться привести к меньшим значениям цикломатической сложности!
P.S.: Думаю, что еще одна область применения алгоритма оценки — это написание на его основе нового «правила проверки» для конфигурации «1С:Автоматизированная проверка конфигураций». Плюс в том, что там уже есть готовые функции «ПолучитьТекстМодуля(ИмяМодуля)», «ПолучитьСтруктуруМодуля(ИмяМодуля)»
отчет работает 🙂
показывает что надо, правильно.
Только оно не поможет заставить программистов исправить свой код,
скажут что у меня сложные вычисления поэтому и сложный код..
(у меня доходит до 37 ЦС, у коллеги до 75 ЦС)
(23) ManyakRus, как показывает практика, задачи класса «заставить людей что-то делать» или «заставить людей что-то делать так, как нужно» решаются другими способами. 🙂 Это отдельная область знаний.
Понадобилось воспользоваться обработкой… Нашел ошибку: считаются лексемы «Тогда», но не считаются «тогда» и тому подобное. Понятно, при подсчете нужно приводить строки к одному регистру. Кстати, непонятно почему не используется встроенная функция СтрЧислоВхождений(<Строка>, <ПодстрокаПоиска>), а написана своя.
(25) ildarovich, Спасибо за замечание, выложил исправленную версию.
Свой метод подсчета вхождений пришлось писать потому, что СтрЧислоВхождений не умеет искать в режиме «слово целиком», то есть, он посчитает вхождения инструкций в идентификаторы.
Протестируем все свои наработки. Спасибо за отчет!
Надо эту характеристику рассматривать не как главный критерий написания кода, который нужно минимизировать, а как одно из ограничений. А то подобный догматизм может привести к таким бесполезным вещам, как «Индусский код».
И получается, что оператор ветвления в цикле нужно считать не за единицу, а умножать на количество циклов. Интересно посмотреть, что за граф построите в алгоритме сортировки.
И оператором ветвления является не только «Если», но и «Попытка».
Похоже, разработчик уже не поддерживает обработку, т.к. был на сайте в 2015 году.
Кто будет пользовать — в обработке нужно фикс сделать:
Показать
Не, вставленный сходу фикс искажает алгоритмы и формирует неверный результат. Надо все-таки еще подумать.
А смысл фикса задумывался в том, чтобы выйти из бесконечного цикла.