Очевидно, что самыми простыми и эффективными в реализации являются системы управления на базе измеримых характеристик объекта. В полной мере это справедливо и по отношению к программным проектам. Однако процесс создания ПО настолько многогранен и одновременно сложен для восприятия, что даже незначительные недостатки системы измерения неизбежно отразятся на качестве управления. Поскольку основу любой системы измерения составляют отдельные показатели (именуемые также метриками), в рамках данной статьи мы попытаемся рассмотреть наиболее актуальные из них для программных проектов.
Метрики программных проектов - это количественные показатели, отражающие их отдельные характеристики. Точнее, метрики представляют собой все, что можно измерить, при условии, конечно, что в этом есть смысл.
Самой распространенной метрикой исходного кода ПО, отражающей размер программного проекта, является показатель количества строк кода (Source Lines Of Code, SLOC). Не вдаваясь в очередное перечисление недостатков данной метрики, рассмотрим особенности ее вычисления, а также существующие разновидности и производные.
Первоначально SLOC применялся в условиях, когда языки программирования обладали относительно простой структурой и для них характерным было соответствие одной строки кода одной команде языка. Со временем языки программирования эволюционировали, стали гораздо гибче, и это соответствие для них больше не выполнялось - одна физическая строка кода теперь может содержать несколько команд языка. С учетом этого выделялись и две основные разновидности показателя SLOC:
Литера "D" (Delivered) означает "поставленный" код, т. е. только вошедший в законченный программный продукт. Очень часто возникает необходимость учитывать не только поставленный код, но и вспомогательный или промежуточный, который не входит в законченный продукт, но нужен для реализации проекта и требует определенных затрат труда.
Что касается вычисления показателя SLOC, то здесь следует отметить, что не существует единственного общепризнанного подхода, приемлемого для различных языков программирования и ориентированного на универсальное применение. Чаще всего SLOC определяется как общее число строк кода за исключением пустых строк и комментариев. В большинстве случаев подсчитывается именно число "физических" SLOC, и наличие нескольких операторов на одной строке не учитывается. Также отметим, что если в контексте SLOC конкретный язык программирования не называется, это обычно означает, что речь идет о величине, выраженной в базовых единицах, - количестве строк кода языка Basic Assembler. Для сопоставления значений показателя для различных языков программирования применяются специальные таблицы преобразования.
Нередко показатель SLOC используется на ранних стадиях работы над проектом с целью получения предварительных оценок ее общего объема. И хотя задача эта достаточно сложная, а о получении точных оценок не может быть и речи, для ее решения есть специальные подходы, обеспечивающие приемлемый результат:
Для метрики SLOC имеется много производных, призванных получить отдельные показатели проекта. Основными среди них являются:
Также наряду со SLOC применяются другие показатели, отражающие количественную оценку отдельных составляющих проекта: число модулей, функций/методов, классов, страниц документации и пр. Однако помимо метрик, подсчитывающих число элементов проекта, к метрикам размера следует отнести также функциональные точки (Function Points, FP), их производные и разновидности, вычисляемые на базе не исходного кода, а пользовательских требований, спецификаций, описаний прецедентов (например, точки прецедентов, Use Case Points, UCP) и пр. В большинстве случаев главное предназначение этой группы метрик, независимо от способа их вычисления, состоит в том, чтобы оценить объем работ по проекту, и, соответственно, быть основой для таких показателей, как стоимость и длительность его реализации.
Другая распространенная группа метрик программных проектов - показатели, характеризующие их сложность. Эти метрики используются главным образом для апостериорного анализа, однако могут применяться и на ранних стадиях работы при осуществлении проектирования.
Основная цель метрик сложности - выявить наиболее критичные участки программного проекта, которые являются потенциальными источниками ошибок и повышенных рисков на всех стадиях его жизненного цикла.
Одна из самых распространенных таких метрик - цикломатическая сложность, впервые предложенная Томасом МакКейбом (Thomas McCabe) в 1976 г. Данная метрика предназначена для оценивания сложности потока управления программы (control flow graph) и вычисляется на основе ориентированного графа, где вычислительные операторы или выражения представляются в виде узлов, а передача управления между узлами - в виде дуг.
Формула вычисления цикломатической сложности выглядит следующим образом:
C = e - n + p,
где e - число ребер, n - число узлов, p - число соединенных компонент графа управляющей логики. Упрощенно формулу можно рассматривать как количество ветвлений, которые может проходить программа, увеличенное на единицу.
Как правило, при вычислении цикломатической сложности логические операторы не принимаются во внимание, допускается также упрощенный подход, в соответствии с которым собственно построение графа не производится, а показатель определяется на основании подсчета числа операторов управляющей логики (if, switch и т. д.) и возможного количества путей исполнения программы. Метрика цикломатической сложности может быть рассчитана для модуля, метода и других структурных единиц программы.
В процессе анализа значений показателя для отдельных структурных элементов можно выявить элементы с высоким значением показателя (к примеру, нормальное значение показателя для метода - не выше 5-7), что свидетельствует о сложности их управляющей логики и, соответственно, высоких трудозатратах на разработку, тестирование и сопровождение.
Вычисление метрики в ходе реализации проекта (а при детальном проектировании оно возможно еще на этом этапе, не дожидаясь стадии кодирования) позволяет своевременно определить наиболее сложные, сопровождающиеся высокими рисками, структурные единицы и принять меры по устранению рисков за счет внесения коррективов.
Для метрики цикломатической сложности существует множество вариаций, в частности:
В целом, метрики цикломатической сложности являются весьма хорошим способом своевременно зажечь перед разработчиками "красный свет", прекратить дальнейшее усложнение отдельных составляющих проекта и упростить их, предупредив вероятные проблемы с запутанным и нестабильным кодом в будущем.
Помимо своих разновидностей, метрика цикломатической сложности стала основой для создания производных и качественно новых метрик, таких как интервальная метрика Дж. Майерса (G. Mayers) - рассчитывается как разность значений цикломатической сложности и числа отдельных условий плюс единица, метрика У. Хансена (W. Hansen) - определяется парой "цикломатическая сложность" и "число операторов", метрика Пивоварского - вычисляется на основе модифицированной цикломатической сложности и позволяет учитывать структурированность программы, выявляя код с плохой структурой, и многих других, нередко имеющих скорее научную, чем практическую ценность.
В 1977 г. Морисом Холстедом (Maurice H. Halstead) была предложена группа метрик, построенных на анализе числа строк и синтаксических элементов исходного кода программы. Основу метрик Холстеда составляют следующие характеристики:
Исходя из этих характеристик, рассчитываются такие оценки:
Далее вычисляется оценка сложности программы (Halstead Difficulty, HDiff):
На основе HDiff предлагается оценивать усилия программиста при разработке с помощью показателя HEff (Halstead Effort):
HEff = HDiff × HPVol.
Несмотря на теоретическую возможность получения предварительных оценок трудоемкости проекта с использованием показателя HEff, метрики Холстеда, как правило, вычисляются уже на основе готового исходного кода и применимы для получения апостериорных оценок. Подобно метрикам цикломатической сложности, они могут быть использованы для того, чтобы предотвратить чрезмерное усложнение отдельных структурных элементов программного проекта и роста связанных с этим рисков.
С переходом от структурной к объектно-ориентированной (ОО) парадигме программирования возникла потребность и в создании соответствующих метрик. Поскольку основные элементы конструирования ОО программ - это классы, реализующие функциональность посредством методов, то именно классы и методы являются категориями, которыми преимущественно оперируют ОО метрики. Помимо таких очевидных метрик, как общее число классов, методов, атрибутов, средних показателей числа методов и атрибутов на класс и пр., применяются гораздо более комплексные метрики, с помощью которых можно судить не только об объеме исходного кода ОО проекта, но и о его сложности, качестве, соответствии основным принципам ОО парадигмы и т. д.
К самым распространенными ОО метриками относятся:
Завершая наш далеко не полный обзор метрик программных проектов, можно утверждать, что в настоящий момент существует весьма обширное число показателей, с помощью которых можно измерять множество различных аспектов создания программного обеспечения. Зачастую речь идет не о том, что одна метрика лучше другой. Все они позволяют посмотреть на один и тот же процесс под разными углами зрения, поэтому используются в комплексе и только так могут служить отправной точкой для принятия объективных решений. Поскольку многие метрики достаточно сложны и трудоемки в вычислении, то для их расчета разработано специальное ПО, обзор которого мы попытаемся осуществить в одной из будущих публикаций.
e-mail автора:
[email protected]