Каково увлечение метриками кода?

В последнее время я видел ряд связанных с «кодовыми метриками» вопросов о SO, и вам нужно задаться вопросом, что такое увлечение? Вот несколько недавних примеров:

  • какие показатели кода убеждают вас в том, что код является crappy
  • когда когда-либо количество строк кода полезной метрикой
  • письменные тесты качества

На мой взгляд, никакая метрика не может заменить обзор кода, хотя:

  • некоторые показатели иногда могут указывать места, которые необходимо пересмотреть, и
  • радикальные изменения показателей на коротких временных рамах могут указывать места, которые необходимо пересмотреть

Но я не могу представить ни одного показателя, который сам по себе всегда указывает на «хороший» или «плохой» код.

Есть ли какая-то волшебная проницательность, которую можно получить из кодовых показателей, которые я забыл? Ленькие программисты / менеджеры ищут оправдания, чтобы не читать код? Люди представлены гигантскими устаревшими кодами и ищут место для начала? Что происходит?

Примечание. Я задал некоторые из этих вопросов по конкретным темам как в ответах, так и в комментариях, и не получил никаких ответов, поэтому я подумал, что я должен попросить сообщество вообще, возможно, что-то не хватает. Было бы неплохо запустить пакетное задание метрик, и на самом деле не нужно снова читать код другого человека (или мой собственный), я просто не думаю, что это практично!

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

Ответы в этой теме немного странные, о чем они говорят:

  • «команда», как «один и единственный бенефициарий» этих указанных показателей;
  • «метрики», как будто они что-то значат сами по себе.

1 / Метрики не для одной популяции, а для трех :

  • разработчики: они занимаются мгновенными статическими кодовыми метриками, касающимися статического анализа их кода (циклическая сложность, качество комментариев, количество строк, …)
  • руководители проектов: они занимаются ежедневными показателями живого кода, исходящими из модульного теста, охвата кода, непрерывного тестирования интеграции
  • бизнес-спонсоры (они всегда забыты, но они являются заинтересованными сторонами, которые платят за разработку): они связаны с еженедельными глобальными кодовыми метриками, касающимися архитектурного проектирования, безопасности, зависимостей, …

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

2 / Метрики сами по себе представляют собой моментальный снимок кода, а это значит … ничего!

Это комбинация этих показателей и комбинации тех разных уровней анализа, которые могут указывать на «хороший» или «плохой» код, но, что более важно, именно тенденция этих показателей значительна.

Это повторение этих показателей, что даст реальную добавленную стоимость, так как они помогут менеджерам / разработчикам / разработчикам / разработчикам бизнеса определить приоритеты среди различных возможных исправлений кода


Другими словами, ваш вопрос о «увлечении метриками» может относиться к разнице между:

  • «красивый» код (хотя это всегда в глазах наблюдателя-кодера)
  • «хороший» код (который работает и может доказать, что он работает)

Так, например, функция с циклической сложностью 9 может быть определена как «красивая», а не одна длинная запутанная функция цикломатической сложности 42.

Но если:

  • последняя функция имеет устойчивую сложность в сочетании с охватом кода 95%,
  • тогда как первый имеет все большую сложность, в сочетании с охватом … 0%,

можно утверждать:

  • последний представляет собой « хороший » код (он работает, он стабилен, и если его нужно изменить, можно проверить, продолжает ли он работать после модификаций),
  • первый – это « плохой » код (ему все равно нужно добавить некоторые случаи и условия, чтобы охватить все, что он должен делать, и нет простого способа сделать некоторый регрессионный тест)

Итак, подведем итог:

единственная метрика, которая сама по себе всегда указывает […]

: не так много, за исключением того, что код может быть более «красивым», что само по себе не означает много …

Есть ли какая-то волшебная проницательность, которую можно получить из кодовых показателей, которые я забыл?

Только комбинация и тенденция метрик дают реальную «магическую проницательность», которой вы пользуетесь.

У меня был проект, который я сделал как однолюбое задание, измеренное для циклической сложности месяц назад. Это было мое первое знакомство с этими метриками.

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

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

В конце концов, я почти всегда мог придумать лучшее решение и гораздо более чистый код. Производительность не пострадала от этого (поверьте мне – я параноик по этому поводу, и я часто проверяю parsingку выхода компилятора).

Я считаю, что показатели – это хорошая вещь, если вы используете их в качестве причины / мотивации для улучшения вашего кода. Истребитель знать, когда остановиться и попросить разрешение на получение метрики.

Метрики – это путеводители и помогают, а не сами по себе.

Лучшей метрикой, которую я когда-либо использовал, является оценка CRAP. http://www.artima.com/weblogs/viewpost.jsp?thread=215899

В основном это алгоритм, который сравнивает взвешенную циклическую сложность с автоматизированным тестированием. Алгоритм выглядит так: CRAP(m) = comp(m)^2 * (1 – cov(m)/100)^3 + comp(m) где comp (m) – цикломатическая сложность метода m, а cov (m) – это покрытие тестового кода, предоставляемое автоматическими тестами.

Авторы вышеупомянутой статьи (пожалуйста, прочитайте ее … это стоит вашего времени), предложите максимальный балл CRAP 30, который разбивается следующим образом:

 Method's Cyclomatic Complexity % of coverage required to be below CRAPpy threshold ------------------------------ -------------------------------- 0 – 5 0% 10 42% 15 57% 20 71% 25 80% 30 100% 31+ No amount of testing will keep methods this complex out of CRAP territory. 

Как вы быстро видите, метрическая наgradleа написания кода, который не является сложным в сочетании с хорошим охватом тестированием (если вы пишете блок-тесты, и вы должны быть, и не измеряете охват … ну, вам, вероятно, понравится плевать на ветер также). 😉

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

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

Для меня самой важной метрикой, которая идентифицирует плохой код, является циклическая сложность. Почти все методы в моих проектах ниже CC 10, и ошибки неизменно обнаруживаются в унаследованных методах с CC более 30. High CC обычно указывает:

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

Хороший обзор кода не заменяет хороший инструмент статического анализа, который, конечно же, не заменяет хороший набор модульных тестов, теперь модульные тесты не подходят без набора приемочных тестов ……

Метрики кода – еще один инструмент, который можно поместить в свой ящик для инструментов, они сами по себе не являются решением, они просто инструмент, который будет использоваться по мере необходимости (конечно, все остальные инструменты в вашем ящике!).

Мое очень субъективное мнение состоит в том, что кодовые метрики выражают непреодолимое институциональное увлечение тем, что они способны количественно определить что-то неотъемлемо не поддающееся количественной оценке.

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

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

Не сказать, что я считаю, что это хорошая мера, только я вижу, что она является неотъемлемой частью ее. И, как вы указали, есть, вероятно, несколько разумных показателей (много 500 линейных методов, высокая сложность – возможно, плохая). Тем не менее, я никогда не был в месте, которое купило это.

Есть одна метрика кода, в которую я верю.

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

Чем меньше это число, тем лучше.

Люди обращаются к идее механистических способов понять и описать код. Если это правда, подумайте о последствиях для эффективности и производительности!

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

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

Я думаю, что если мы используем метрики как предложение – красный флаг – возможно, они могут быть полезны. Проблема в том, что люди начинают измерять производительность в SLOC или качество в процентах от линий с помощью тестов.

Метрики и автоматические тесты не предназначены для полной проверки кода.

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

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

Измерения полезны только в том случае, если:

  • Команда разработала их
  • Команда согласилась с ними
  • Они используются для определения конкретной области

В общем, любая метрика, которая не вписывается в это, будет страдать от команды, оптимизирующей ее. Вы хотите измерить строки кода? Честно говоря, сколько можно писать! Вы хотите измерить охват кода, golly, наблюдайте, как я покрываю этот код!

Я думаю, что показатели могут быть полезны для определения тенденций, и на самом деле я видел некоторые полезные, такие как построение графика при разрыве сборки, сбой кода (количество строк кода, изменяющихся по всему проекту) и другие вещи. Но если команда не подходит с ними, или они не согласны или не понимают их, вы, вероятно, находитесь в мире боли.

Вот некоторые показатели сложности из stan4j (http://stan4j.com/).

Инструмент анализа структуры classа eclipse.

Мне нравится этот инструмент и показатели. Я рассматриваю показатели как статистику, индикаторы, предупреждающие сообщения. Когда-то из-за некоторых методов или некоторых classов действительно была сложная логика, которая делала их сложными, что должно быть сделано, следите за ними, проверяйте их, нужно ли им реорганизовывать их или тщательно их просматривать, они подвержены ошибкам. Кроме того, я использую его как инструмент анализа, чтобы изучить исходный код, из-за того, что мне нравится учиться от сложного до простого. Фактически он включает в себя некоторые другие показатели, такие как Robert C. Martin Metrics, Chidamber & Kemerer Metrics, Count Metrics Но мне это нравится

Показатели сложности

Циклические показатели сложности

Cyclomatic Complexity (CC) Цикломатическая сложность метода – это количество точек принятия решения в графе streamа управления методом, увеличивающемся на единицу. Точки решения встречаются в случаях, когда / for / while, предложения case / catch и аналогичные элементы исходного кода, где stream управления не только линейный. Количество пунктов решения (байтового кода), введенных одним (исходным кодом), может различаться, в зависимости, например, от сложности булевых выражений. Чем выше значение циклометрической сложности метода, тем больше тестовых случаев требуется для проверки всех ветвей графа streamа управления методом.

Средняя циклическая сложность Среднее значение метрики Cyclomatic Complexity по всем методам приложения, библиотеки, дерева пакетов или пакета.

Жирные показатели Матовая метрика артефакта – это количество ребер в соответствующем графике зависимостей артефакта. Тип графика зависимости зависит от варианта метрики и выбранного артефакта:

Жир . Матовая метрика дерева приложения, библиотеки или пакета – это счетчик графа его графа зависимости поддерева. Этот график содержит все дочерние артефакты в иерархии дерева пакетов, а также включает в себя листовые пакеты. (Чтобы увидеть соответствующий график в представлении компоновки, необходимо отключить переключение «Плоские пакеты» проводника структуры. Переключатель «Показать библиотеки» должен быть включен, если выбранный артефакт является библиотекой, иначе он должен быть отключен.)

Матовая метрика пакета – это счетчик грани его графа зависимости от единицы. Этот график содержит все classы верхнего уровня пакета.

Матовая метрика classа – это счетчик графа его члена. Этот график содержит все поля, методы и classы членов classа. (Этот график и значение Fat доступны только в том случае, если анализ кода был выполнен с помощью элемента детализации детализации, а не classа).

Жир для зависимостей библиотек (Fat – Libraries) Метрика приложения Fat for Library Dependencies – это счетчик грани его графа зависимости библиотеки. Этот график содержит все библиотеки приложения. (Чтобы увидеть соответствующий граф в представлении композиции, необходимо включить переключатель «Показать библиотеки библиотек»).

Fat for Flat Package Dependencies (Fat – Packages). Показатель Dependencies Fat для плоских пакетов – это счетчик границ его плоского графика зависимости пакета. Этот график содержит все пакеты приложения. (Чтобы увидеть соответствующий график в представлении композиций, необходимо включить переключатель Flat Packages в конструкторе структуры, а переключатель «Показать библиотеки» должен быть отключен.)

Метрика Fat for Flat Package Dependencies – это счетчик грани его графа зависимости плоского пакета. Этот график содержит все пакеты библиотеки. (Чтобы увидеть соответствующий график в представлении компоновки, должны быть включены переключатели «Плоские пакеты» и «Показать библиотеки» в проводнике структуры.)

Fat для зависимостей classа верхнего уровня (Fat – Units) Показатель Fat для classа верхнего уровня Зависимость показателя приложения или библиотеки – это счетчик границ его графа зависимости от единицы. Этот график содержит все classы верхнего уровня приложения или библиотеки. (Для разумных приложений он слишком велик, чтобы быть визуализированным и, следовательно, не может отображаться в представлении композиций. Графики зависимостей единиц могут отображаться только для пакетов.)

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

Ох … и это предполагает, что по крайней мере один из участников вашего обзора кода имеет ключ.

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

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

Одна часть ответа заключается в том, что некоторые кодовые метрики могут дать вам очень быстрый первоначальный удар при ответе на вопрос: что это за код?

Даже «строки кода» могут дать вам представление о размере базы кода, на которую вы смотрите.

Как уже упоминалось в другом ответе, тренд метрик дает вам наибольшую информацию.

Метрики сами по себе не особо интересны. Это то, что вы делаете с ними, что имеет значение.

Например, если вы измеряли количество комментариев на строку кода, что бы вы считали хорошим значением? Кто знает? Или, что еще важнее, у каждого свое мнение.

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

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

edit: В ответ на комментарии Стивена А. Лоу – это абсолютно правильно. В любом анализе данных необходимо быть осторожным, чтобы различать причинную связь и простое соотношение. Важен выбор метрик на основе пригодности. Нет смысла пытаться измерять потребление кофе и атрибутировать качество кода (хотя я уверен, что некоторые пробовали ;-))

Но прежде чем вы сможете найти отношения (причинные или нет), вы должны иметь данные.

Выбор данных для сбора зависит от того, какой процесс вы хотите проверить или улучшить. Например, если вы пытаетесь проанализировать успех ваших процедур проверки кода (используя свое собственное определение для «успеха», будь то уменьшенные ошибки или уменьшенные ошибки кодирования или более короткое время поворота или что-то еще), вы выбираете показатели, которые измеряют общая частота ошибок и количество ошибок в проверенном коде.

Поэтому, прежде чем собирать данные, вы должны знать, что вы хотите с ними делать. Если метрика – это средство, каков конец?

Я не думаю, что небольшие изменения в показателях имеют смысл: функция со сложностью 20 не обязательно более чистая, чем функция со сложностью 30. Но стоит искать показатели, чтобы искать большие различия.

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

Мы программисты. Нам нравятся номера.

Кроме того, что вы собираетесь делать, НЕ описывайте размер кодовой базы, потому что «строки метрик кода неактуальны»?

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

Давайте будем гением компьютера.