Рубрики

Свежие записи

Метрики кода и их практическая реализация в IBM Rational ClearCase

GD Star Rating
loading...
GD Star Rating
loading...




Автор: Новичков Александр, руководитель отдела внедрения и консалтинга, СМ-Консалт
Статья опубликована на сайте IBM

Никогда не ставьте задачу, решение которой вам неизвестно.

Правило Берке

Решение сложной задачи поручайте ленивому

сотруднику — он найдет более легкий путь.

Закон Хлейда

Данная статья описывает ряд моментов использования IBM Rational ClearCase и предполагает, что читатель знаком с данным продуктом и дисциплиной «Управление Конфигурациями». Для ознакомления воспользуйтесь следующими ссылками:

Оглавление

1      Введение.

2      Метрики.

2.1       Размерно-ориентированные метрики (показатели оценки объема)

2.1.1        LOC-оценка (Lines Of Code)

2.1.1.1     Метрика стилистики и понятности программ..

2.1.2        Итого по SLOC..

2.2       Метрики сложности.

2.2.1        Объектно-ориентированные метрики.

2.2.2        Метрики Холстеда.

2.2.3        Метрики цикломатической сложности по Мак-Кейбу.

2.2.4        Метрики Чепина. 11

2.3       Предварительная оценка на основе статистических методов  в зависимости от этапов разработки программы..

2.3.1        Предварительная оценка сложности программы на этапе разработки спецификации требований к программе.

2.3.2        Предварительная оценка сложности на этапе  определения архитектуры..

2.4       Подведение итогов.

3      Практическая реализация применения метрических показателей  в IBM Rational ClearCase

3.1       Общая информация.

3.2       Определение требований к примеру.

3.3       Реализация требований в IBM Rational ClearCase.

3.3.1        Реализация пунктов 1 и 2: выбор метрик и определение способа хранения.

3.3.2        Реализация пункта 3: выбор метода сбора информации.

3.3.3        Реализация пункта 4: определение способа представления.

3.3.4        Реализация пункта 5: «бантики». Формирование контекстного меню и подсчет метрики LOC для подсистем и проекта вцелом..

4      Заключение.

5      Литература.

6      Ресурсы интернет.

1. Введение

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

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

Современные комплексные системы оценки характеристик проектов создания ПО могут быть использованы для решения следующих задач:

  • предварительная, постоянная и итоговая оценка экономических параметров проекта: трудоемкость, длительность, стоимость;
  • оценка рисков по проекту: риск нарушения сроков и невыполнения проекта, риск увеличения трудоемкости на этапах отладки и сопровождения проекта и пр.;
  • принятие оперативных управленческих решений – на основе отслеживания определенных метрик проекта можно своевременно предупредить возникновение нежелательных ситуаций и устранить последствия непродуманных проектных решений.

2. Метрики

Метрики сложности программ принято разделять на три основные группы:

  • метрики размера программ;
  • метрики сложности потока управления программ;
  • метрики сложности потока данных программ.

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

Метрики второй группы базируются на анализе управляющего графа программы. Представителем данной группы является метрика Маккейба.

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

Метрики третьей группы базируются на оценке использования, конфигурации и размещения данных в программе. В первую очередь это касается глобальных переменных. К данной группе относятся метрики Чепина.

2.1 Размерно — ориентированные метрики (показатели оценки объема)

2.1.1 LOC-оценка (Lines Of Code)

Размерно-ориентированные метрики прямо измеряют программный продукт и процесс его разработки. Основываются такие метрики на LOC-оценках.

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

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

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

На основе этих данных обычно подсчитываются простые метрики для оценки производительности труда (KLOC/человеко-месяц) и качества изделия.

Эти метрики не универсальны и спорны, особенно это относится к такому показателю как LOC, который существенно зависит от используемого языка программирования.

Пример из жизни:
На наш взгляд оценка по количеству строк в коде влечёт за собой соблазн написать побольше строк, дабы взять побольше денег. Разумеется, об оптимизации в таком продукте никто уже думать не станет. Вспомним историю о том, как планетарный центр аутсорсинга — Индия, после того, как заказчики вменили им метрику LOC, на второй день показал удвоение и утроение строк кода.

 

Количество строк исходного кода (Lines of Code – LOC, Source Lines of Code – SLOC) является наиболее простым и распространенным способом оценки объема работ по проекту.

Изначально данный показатель возник как способ оценки объема работы по проекту, в котором применялись языки программирования, обладающие достаточно простой структурой: «одна строка кода = одна команда языка». Также давно известно, что одну и ту же функциональность можно написать разным количеством строк, а если возьмем язык высокого уровня (С++, Java), то возможно и в одной строке написать функционал 5-6 строк – это не проблема. И это было бы полбеды: современные средства программирования сами генерируют тысячи строк кода на пустяковую операцию.

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

В зависимости от того, каким образом учитывается сходный код, выделяют два основных показателя SLOC:

  1. количество «физических» строк кода – SLOC (используемые аббревиатуры LOC, SLOC, KLOC, KSLOC, DSLOC) – определяется как общее число строк исходного кода, включая комментарии и пустые строки (при измерении показателя на количество пустых строк, как правило, вводится ограничение – при подсчете учитывается число пустых строк, которое не превышает 25% общего числа строк в измеряемом блоке кода).
  2. Количество «логических» строк кода – SLOC (используемые аббревиатуры LSI, DSI, KDSI, где «SI» — source instructions) – определяется как количество команд и зависит от используемого языка программирования. В том случае, если язык не допускает размещение нескольких команд на одной строке, то количество «логических» SLOC будет соответствовать числу «физических», за исключением числа пустых строк и строк комментариев. В том случае, если язык программирования поддерживает размещение нескольких команд на одной строке, то одна физическая строка должна быть учтена как несколько логических, если она содержит более одной команды языка.

Для метрики SLOC существует большое число производных, призванных получить отдельные показатели проекта, основными среди которых являются:

  • число пустых строк;
  • число строк, содержащих комментарии;
  • процент комментариев (отношение строк кода к строкам комментария, производная метрика стилистики);
  • среднее число строк для функций (классов, файлов);
  • среднее число строк, содержащих исходный код для функций (классов, файлов);
  • среднее число строк для модулей.

2.1.1.1 Метрика стилистики и понятности программ

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

Fi = SIGN (Nкомм. i / Ni – 0,1)

Общая оценка <!—[if !vml]—><!—[endif]—>

Суть метрики проста: код разбивается на n-равные куски и для каждого из них определяется Fi

2.1.2 Итого по SLOC

Потенциальные недостатки SLOC, на которые нацелена критика:

  • некрасиво и неправильно сводить оценку работы человека к нескольким числовым параметрам и по ним судить о производительности. Менеджер может назначить наиболее талантливых программистов на сложнейший участок работы; это означает, что разработка этого участка займёт наибольшее время и породит наибольшее количество ошибок, из-за сложности задачи. Не зная об этих трудностях, другой менеджер по полученным показателям может решить, что программист сделал свою работу плохо.
  • Метрика не учитывает опыт сотрудников и их другие качества
  • Искажение: процесс измерения может быть искажён за счёт того, что сотрудники знают об измеряемых показателях и стремятся оптимизировать эти показатели, а не свою работу. Например, если количество строк исходного кода является важным показателем, то программисты будут стремиться писать как можно больше строк и не будут использовать способы упрощения кода, сокращающие количество строк (см. врезку про Индию).
  • Неточность: нет метрик, которые были бы одновременно и значимы и достаточно точны. Количество строк кода — это просто количество строк, этот показатель не даёт представления о сложности решаемой проблемы. Анализ функциональных точек был разработан с целью лучшего измерения сложности кода и спецификации, но он использует личные оценки измеряющего, поэтому разные люди получат разные результаты.

И главное помнить: метрика SLOC не отражает трудоемкости по созданию программы .

Пример из жизни :
В одной из компаний при внедрении мы применили данную метрику – считали строки кода. Руководитель организации был в отпуске, но по возвращении из него решил воспользоваться прозрачностью и трассируемостью изменений и посмотреть, как же идут дела в проектах у его менеджеров. И чтоб полностью войти в курс, опустился на самый низкий уровень (то есть не стал оценивать плотность дефектов, количество исправленных багов) – на уровень исходных текстов. Решил посчитать, кто и сколько строк написал. А чтоб было совсем весело – соотнести количество рабочих дней в неделю и количество написанного кода (логика проста: человек работал 40 часов в неделю, значит, должен много чего написать). Естественно, нашелся человек, который за неделю написал всего одну строку, даже не написал, а только откорректировал существующую…
Гневу руководителя не было предела – нашел бездельника! И плохо было бы программисту, если бы менеджер проекта не объяснил, что: была найдена ошибка в программе, нашел ее VIP- клиент, ошибка влияет на бизнес клиента и ее нужно было срочно устранить, для этого был выбран вот этот конкретный исполнитель, который развернул стенд, залил среду клиента, подтвердил проявление ошибки и начал ее искать и устранять. Естественно, в конце концов, он поменял фрагмент кода, в котором было неправильное условие и все заработало.

Согласитесь, считать трудозатраты по данной метрике глупо – необходима комплексная оценка…

2.2 Метрики сложности

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

2.2.1 Объектно-ориентированные метрики

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

Взвешенная насыщенность класса 1 (Weighted Methods Per Class (WMC)

Взвешенная насыщенность класса 2 (Weighted Methods Per Class (WMC2))

Глубина дерева наследования (Depth of inheritance tree)

Количество детей (Number of children)

Отклик на класс (Response For Class)

Метрика Описание
Отражает относительную меру сложности класса на основе цикломатической сложности каждого его метода. Класс с более сложными методами и большим количеством методов считается более сложным. При вычислении метрики родительские классы не учитываются.
Мера сложности класса, основанная на том, что класс с большим числом методов, является более сложным, и что метод с большим количеством параметров также является более сложным. При вычислении метрики родительские классы не учитываются.
Длина самого длинного пути наследования, заканчивающегося на данном модуле. Чем глубже дерево наследования модуля, тем может оказаться сложнее предсказать его поведение. С другой стороны, увеличение глубины даёт больший потенциал повторного использования данным модулем поведения, определённого для классов-предков.
Число модулей, непосредственно наследующих данный модуль.Большие значения этой метрики указывают на широкие возможности повторного использования; при этом слишком большое значение может свидетельствовать о плохо выбранной абстракции.
Связность объектов (Coupling between objects) Количество модулей, связанных с данным модулем в роли клиента или поставщика. Чрезмерная связность говорит о слабости модульной инкапсуляции и может препятствовать повторному использованию кода.
Количество методов, которые могут вызываться экземплярами класса; вычисляется как сумма количества локальных методов, так и количества удаленных методов

2.2.2 Метрики Холстеда

Метрика Холстеда относится к метрикам, вычисляемым на основании анализа числа строк и синтаксических элементов исходного кода программы.

Основу метрики Холстеда составляют четыре измеряемые характеристики программы:

  • NUOprtr (Number of Unique Operators) — число уникальных операторов программы, включая символы-разделители, имена процедур и знаки операций (словарь операторов);
  • NUOprnd (Number of Unique Operands) — число уникальных операндов программы (словарь операндов);
  • Noprtr (Number of Operators) — общее число операторов в программе;
  • Noprnd (Number of Operands) — общее число операндов в программе.

На основании этих характеристик рассчитываются оценки:

  • Словарь программы (Halstead Program Vocabulary, HPVoc): HPVoc = NUOprtr + NUOprnd;
  • Длина программы (Halstead Program Length, HPLen): HPLen = Noprtr + Noprnd;
  • Объем программы (Halstead Program Volume, HPVol): HPVol = HPLen log2 HPVoc;
  • Сложность программы (Halstead Difficulty, HDiff): HDiff = (NUOprtr/2) × (NOprnd / NUOprnd);
  • На основе показателя HDiff предлагается оценивать усилия программиста при разработке при помощи показателя HEff (Halstead Effort): HEff = HDiff × HPVol.

2.2.3 Метрики цикломатической сложности по Мак-Кейбу

Показатель цикломатической сложности является одним из наиболее распространенных показателей оценки сложности программных проектов. Данный показатель был разработан ученым Мак-Кейбом в 1976 г., относится к группе показателей оценки сложности потока управления программой и вычисляется на основе графа управляющей логики программы (control flow graph). Данный граф строится в виде ориентированного графа, в котором вычислительные операторы или выражения представляются в виде узлов, а передача управления между узлами – в виде дуг.

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

Упрощенная формула вычисления цикломатической сложности представляется следующим образом:

C = e – n + 2,

где e – число ребер, а n – число узлов на графе управляющей логики.

Как правило, при вычислении цикломатической сложности логические операторы не учитываются.

В процессе автоматизированного вычисления показателя цикломатической сложности, как правило, применяется упрощенный подход, в соответствии с которым построение графа не осуществляется, а вычисление показателя производится на основании подсчета числа операторов управляющей логики (if, switch и т.д.) и возможного количества путей исполнения программы.

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

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

Существует значительное количество модификаций показателя цикломатической сложности.

  • «Модифицированная» цикломатическая сложность – рассматривает не каждое ветвление оператора множественного выбора (switch), а весь оператор как единое целое.
  • «Строгая» цикломатическая сложность – включает логические операторы.
  • «Упрощенное» вычисление цикломатической сложности – предусматривает вычисление не на основе графа, а на основе подсчета управляющих операторов.

2.2.4 Метрики Чепина

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

Суть метода состоит в оценке информационной прочности отдельно взятого программного модуля с помощью анализа характера использования переменных из списка ввода-вывода.

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

  1. Множество «Р» – вводимые переменные для расчетов и для обеспечения вывода. Примером может служить используемая в программах лексического анализатора переменная, содержащая строку исходного текста программы, то есть сама переменная не модифицируется, а только содержит исходную информацию.
  2. Множество «М» – модифицируемые или создаваемые внутри программы переменные.
  3. Множество «C» – переменные, участвующие в управлении работой программного модуля (управляющие переменные).
  4. Множество «Т» – не используемые в программе (“паразитные”) переменные. Поскольку каждая переменная может выполнять одновременно несколько функций, необходимо учитывать ее в каждой соответствующей функциональной группе.

Далее вводится значение метрики Чепина:

Q = a1P + a2M + a3C + a4T, где a1, a2, a3, a4 – весовые коэффициенты.

Весовые коэффициенты использованы для отражения различного влияния на сложность программы каждой функциональной группы. По мнению автора метрики наибольший вес, равный трем, имеет функциональная группа С, так как она влияет на поток управления программы. Весовые коэффициенты остальных групп распределяются следующим образом: a1=1; a2=2; a4=0.5. Весовой коэффициент группы T не равен нулю, поскольку “паразитные” переменные не увеличивают сложности потока данных программы, но иногда затрудняют ее понимание. С учетом весовых коэффициентов выражение примет вид:

Q = P + 2M + 3C + 0.5T .

2.3 Предварительная оценка на основе статистических методов в зависимости от этапов разработки программы

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

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

Выделим типовые этапы в разработке программ:

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

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

2.3.1 Предварительная оценка сложности программы на этапе разработки спецификации требований к программе

Для оценки по результатам работы данного этапа может быть использована метрика прогнозируемого числа операторов Nпрогн программы:

Nпрогн =NF*Nед

Где: NF – количество функций или требований в спецификации требований к разрабатываемой программе;
Nед – единичное значение количества операторов (среднее число операторов, приходящихся на одну среднюю функцию или требование). Значение Nед — статистическое.

2.3.2 Предварительная оценка сложности на этапе определения архитектуры

Си = NI / (NF * NIед * Ксл)

Где:
NI – общее количество переменных, передаваемых по интерфейсам между компонентами программы (также является статистической);
NIед–единичное значение количества переменных, передаваемых по интерфейсам между компонентами (среднее число передаваемых по интерфейсам переменных, приходящихся на одну среднюю функцию или требование);
Ксл – коэффициент сложности разрабатываемой программы, учитывает рост единичной сложности программы (сложности, приходящейся на одну функцию или требование спецификации требований к программе) для больших и сложных программ по сравнению со средним ПС.

2.4 Подведение итогов

Таблица 1 – Состав метрик их влияние и анализ эффективности использования

Усилия разработчика при реализации.

Длина и объем программы

Анализ цикломатической сложности.

Усилия программиста при разработке.

Количество строк на реализацию требования.

Количество комментариев на единицу кода.

Прочие количественные метрики (число функций, классов, файлов).

Плотность дефектов на единицу кода.

Метрика Зачем нужна Влияет на… Анализ на основе статистических данных (как тренд, так и прогноз)
Насколько эффективен труд разработчика. Точность прогнозов оценки трудоемкости при выполнении организацией типовых или мало отличающихся запросов Можно анализировать усилия разработчика во временном срезе или в срезе по релизам или проектам. Выявлять, на каких задачах программист полностью выкладывается, а какие ему не по душе. Тренд позволит менеджеру лучше понимать, кто и каких задачах максимально эффективен при формировании команды нового проекта, а также какие подсистемы относительно сложны, а какие – просты.
Оценку объема изменений Увеличивается или уменьшается объем программы во времени. Используем для прогноза сложности на ранних этапах на основе статистики.
Оценку сложности изменений Сложность растет или нет? Используем для прогноза сложности на ранних этапах на основе статистики.
Для определения сложности реализации того или иного блока кода (класса, функции и т.д.) Понимание того, насколько интеллектуально-затратной для разработчика была та или иная функция. Анализируется увеличение или уменьшение усилий разработчика во времени. На предварительных этапах метрику можно использовать для прогноза.
Меряем общую температуру. Эта метрика принимается во внимание при анализе реализации запроса. Понимание КПД.Отслеживаем всплески. Сигнал опасности при выявлении увеличения количества строк во время выполнения типового запроса Используем для оценки сложности на ранних этапах на основе статистики.
Код должен быть документирован. Если соотношение кода к комментарию не 1:4, то разработчик обязан доработать. Качество кода, его прозрачность. Общая культура разработчиков растет или нет?
Если растет – хорошо.
Если нет – плохо.
Если скачкообразно – соотносим менеджеров\руководителей проектов со скачками.
Выделяем сложные проекты, проблемные модули или подсистемы
Отношение новых функций к измененным. Количество добавленных, удаленных и измененных строк по отношению к предыдущей версии. Глубокий анализ изменений по релизам (версиям, сборкам) дает понять: Количество изменений (на что угодно) – сколько раз один и тот же блок кода корректировался. Возможно выявить узкое место в программе: интенсивно меняющийся блок кода может влиять на общее качество программы (потенциальное место возникновения ошибок). Возможно, необходимо изменить архитектуру блока.
Количество дефектов на 1-у строку кода Производная метрика: количество строк/число дефектов. Данная метрика более полезна для временной оценки: Плотность увеличивается от билда к билду, от версии к версии? Плотность дефектов по подсистемам (выявляем проблемную подсистему. В этом случае показатель почти наверняка будет коррелироваться с метрикой, отвечающей за интенсивность изменений участка кода, так как в этом месте наверняка «тонко»)

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

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

В следующей части нашей статьи мы рассмотрим практические применения метрик в программных продуктах IBM Rational. Рассмотрим только один сегмент, касающийся способа хранения набора метрик в репозитории системы управления версиями ClearCase . Сразу отметим, что эта система может хранить только метрики, относящиеся к коду. Комбинированные же метрики (такие, как плотность дефектов) необходимо выводить на основе показателей из всех систем: ClearCase (количество строк) и ClearQuest (количество дефектов за единицу времени), RequisitePro (количество требований) и т.д.

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

Метрики размера программы:

  • Метрика Майерса;
  • Метрика Джилба;
  • Метрика ‘Подсчет точек пересечения’;
  • Метод граничных значений.

Метрики сложности потока данных:

  • Метрика ‘модуль – глобальная переменная’;
  • Метрика Спена;
  • Метрика Овьедо.

Методы оценки надежности:

  • Модель Джелинского-Моранды;
  • Модель Шумана;
  • Модель Шика-Уолвертона;
  • Модель ‘Простая экспоненциальная модель’;
  • Модель Липова.

Геометрические модели:

  • Модель Шнейдевинда;
  • Модель Дюэна;
  • Марковская модель;
  • Статистическая модель Миллса;
  • Модель последовательности испытаний Бернулли.

Метрики стилистики и понятности программ:

  • Метрика уровня комментированности программного кода;
  • Метрика изменения длины программной документации.

Объектно-ориентированные метрики:

  • Метрики связности класса (по данным, по методам);
  • Метрика зависимости изменений между классами;
  • Метрика локальности данных класса;
  • Набор метрик Чидамбера и Кемерера (WMC, DIT, NOC, CBO, RFC, LCOM);
  • Набор метрик Лоренца и Кидда (CS, NOO, NOA, SI);
  • Набор метрик Абреу (MHF, AHF, MIF, AIF, POF, COF;
  • Набор метрик тестируемости ОО-систем Байндера.

3. Практическая реализация применения метрических показателей в IBM Rational ClearCase

3.1 Общая информация

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

Взаимосвязи в системе

Рисунок 1 –  Взаимосвязи в системе IBM Rational

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

 

 

Модель трассировки изменений

Рисунок 2 – Модель трассировки изменений. От запроса к коду и обратно

 

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

Полная трассировка, возможность проследить дерево изменений как сверху вниз (от запроса до кода), так и снизу вверх (от кода к запросу).

На рисунке 2 документируется запрос, на его основе формируется одно требование, по которому формируется план работ, с задачами, распределенными между двумя программистами. Что видно сверху (от запроса):

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

Что видно снизу (от кода):

  • автор кода;
  • сколько раз переписывал;
  • количество добавленных комментариев;
  • количество удаленных и добавленных строк;
  • какова сложность написанного кода;
  • какая задача решалась;
  • какое требование реализовывал и на основании какого запроса.

Весь дальнейший материал посвящен только последней подсистеме — ClearCase: мы не будем пытаться связать воедино все метрики, а сконцентрируемся только на метриках кода. Все вышеприведенные примеры взаимодействия были необходимы только для иллюстрации место метрик кода в общем наборе проектных показателей.

Выведем основные:

  • Анализ метрик по релизам (чем версия 2.0 отличается от версии 1.0 в отношении количества затраченного времени на реализацию, количества строк кода, и пр.)
  • Анализ метрик по заказчикам (если выделяются ветви под каждого заказчика)
  • Выборка проектных данных по определенным критериям (проектам, программам, заказчикам, субподрядчикам и.т.п.)

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

  • Историю изменений каждого файла проекта;
  • Историю изменений каталогов проекта (когда и в каком релизе файлы добавлялись в каталог или удалялись);
  • Базовые версии проекта (baseline) – слепки проекта на определенный момент времени – это все зарегистрированные версии проектных файлов, переданных в эксплуатацию или заказчику (релизы, как основные так и промежуточные);
  • Информацию обо всех изменениях кода для всех заказчиков;
  • Информацию обо всех изменениях кода, полученного от субподрядчиков;
  • Самое главное, что для всей информации сохраняется статистика о том кем, когда и с каким комментарием выполнялось то или иное изменение.

Одного хранения метрик мало, необходим еще и анализ. Нам просто необходимо, чтобы система контроля версий была способна давать анализ по КАЖДОМУ атому хранимой в репозитории информации, чтобы возможно было в дальнейшем устраивать многомерный и глубокий анализ не только в статике, но и в динамике (например, от релиза к релизу).

ClearCase как приложение является расширяемым, то есть его можно интегрировать с любым внешним приложением, которое способно собрать метрики. Причем, информацию о показателях важно хранить не в только в базе данных системы сбора метрик, но и в самом ClearCase Благо, сам ClearCase позволяет хранить в себе ЛЮБУЮ дополнительную информацию.

Сбор метрик в ClearCase может организовываться двумя принципиально разными способами:

  • В режиме реального времени – суть метода заключается в том, что ClearCase в момент выполнения активного действия может вызвать для анализа то самое внешнее приложение. Активным действием можно считать такую важную операцию разработчика как регистрация изменений в репозитории (просто check-in)
  • В отложенном режиме – сервер ClearCase сам запускается каждую ночь и собирает метрики для измененных за рабочий день данных. То есть функция обычного коллектора.

Разумное использование обоих методов заключается в предварительном анализе потребностей организации и определяется на начальном этапе вместе с набором собираемых показателей.

Приведем простой пример: одна из многих деятельностей разработчика – формирование измененной версии исходного кода (выполнение операций check-in и check-out). Нам, с точки зрения процесса, важно, чтобы разработчик не смог зарегистрировать в репозитории версию, которая не соответствует корпоративным правилам — например, соотношение LOC и COM – соотношение строк комментария к строкам кода. Соответственно ClearCase должен запретить регистрацию изменений, если они формально не подходят по каким-либо признакам.

Обращаем особое внимание на то, что мы говорим только о КОЛИЧЕСТВЕННЫХ показателях, но никак не о качественных!

Вывод в данной ситуации прост – выбираем систему реального времени для данного вида операции.

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

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

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

Для иллюстрации данного подхода мы взяли одно из средств метрического анализа кода «СССС» и попытались сделать так, чтобы она «обсчитывала» все промежуточные версии, хранимые в системе версионного управления ClearCase. Которые и будут использованы для последующего анализа.
Данная часть статьи предполагает, что читатель более-менее знаком с инструментом ClearCase.

3.2 Определение требований к примеру

Итак, давайте кратко определимся с тем, что мы собираемся сделать:

  1. Выбираем собираемые и хранимые метрики
  2. Определяем способ хранения
  3. Выбираем метод сбора информации
  4. Определяем способ представления
  5. Делаем «бантики»

Сначала о исходных данных. У нас есть некий тестовый пример – репозиторий ClearCase , в котором хранятся файлы проекта С и CPP. Разные файлы корректировались разное количество раз. В репозитории есть две базовые версии «REL1.0» и «REL2.0». Разные файлы по-разному размечались, в соответствии с тем какое количество раз были отредактированы. Репозиторий называется «vvv»

1. Выбираем собираемые и хранимые метрики

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

Собираемые метрики:

  • Number of modules – число модулей
  • Lines of Code – строки кода
  • Lines of Comments – строки комментария
  • McCabe’s Cyclomatic Complexity — цикломатическая сложность
  • Lines of code per line of comment – соотношение строк кода и комментария
  • Cyclomatic Complexity per line of comment — цикломатическая сложность на количество строк

Учитываем, что «a-d» это целые числа, «e» — вещественное число, «f» может являться как вещественным так и простой строкой (для иллюстрации типов, представим, что она будет строкой)

2. Определяем способ хранения

На лекциях очень часто приходится отвечать на вопрос из серии «а может ли ClearCase…». Ответ всегда односложный – «Да, может».

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

Для каждой версии ClearCase позволяет определять состав АТРИБУТОВ, которые будут сопровождать КАЖДУЮ версию файла в репозитории. Состав и число атрибутов – неограниченно.

Атрибут позволяет давать дополнительные описания к версии элемента, к уже существующим комментариям. Например, удобно в качестве дополнительных полей держать атрибуты «warnings» и «errors», которые будут описывать числовые значения, выдаваемые компилятором при компиляции той или иной версии. Во время просмотра дерева историй версий, все атрибуты, связанные с ней (бесконечное число) отображаются наравне с именами меток. Особое значение атрибуты приобретают и при тестировании, если нужно пометить нулем или единицей протестированную версию, то создают атрибут «tested», и соответствующим образом «нумеруют» протестированные версии. Атрибут также может использоваться для хранения меток

Атрибут можно сравнить с переменной, у которой есть НАИМЕНОВАНИЕ и переменное значение. Также у каждого атрибута есть его тип.

Для создания атрибута ему дают имя и тип данных, которые будут храниться.

Существуют следующие предопределенные типы значений:

  • Integer. Целое числовое значение. Подходит для большинства применений;
  • Real. Число с плавающей точкой. Подходит для глубокой нумерации версий;
  • Time. Временное описание;
  • String. Дополнительное символьное описание. Используется в тех случаях, когда одного комментария для описания версии недостаточно, например, для выделения протестированной версии можно просто создать атрибут «tested», а в качестве параметров давать значения «да» или «нет»;
  • Opaque. Произвольный тип значения. Используется в тех случаях, когда тип значения неизвестен изначально (таких ситуаций лучше избегать).

Для типов значений Integer, Real и Time можно задать ограничитель значений (ограничить диапазон вводимых значений).

Для всех типов значений возможно включение пункта «enumeration», для внесения предустановленных значений (например, только 0 и 1 для атрибута тестирования, или «да» и «нет» для него же).

Также удобно пользоваться пунктом default value, устанавливающим начальные значения для атрибута.

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

3. Выбираем метод сбора информации

Здесь все просто. Выбираем отложенный режим. Будем запускать скрипт, анализирующий изменения в каждой версии на дереве версий.

4. Определяем способ представления

Известно, что у ClearCase есть два способа представления информации:

  • Через запрос к репозиторию (в большинстве выполняется через командную строку)
  • Через построение специального представления (в данном представлении собираются только версии файлов, выбранным по специальным критериям)

Нам нужны следующие отчеты (запросы):

  1. Количественный состав изменений второго релиза по отношению к первому (какие именно файлы и каких версий были в первом релизе и какими они стали во втором). Здесь мы получаем количество промежуточных версий и список измененных файлов.
  2. Является производным от первого. Все тоже самое + отображение метрик для каждой версии (оцениваем объем изменений)
  3. Состав изменений (список измененных файлов с метриками)
  4. Суть проведенных изменений (какие строки в каких модулях были изменены). Информацию представляем с включенными фрагментами кода
  5. Отчет обо всех изменениях в файле, с указанием кто, когда и какую конструкцию вносил в файл. Отдельно хочется отметить данный отчет, так как он позволяет каждому новому разработчику анализировать свой модуль на все изменения и получать единым отчетом информацию о его корректировке, что позволяет СУЩЕСТВЕННО экономить время при анализе кода. Простой пример: модуль многократно модифицируется один год. Учитывая, что в ClearCase хранятся все версии (включая экспериментальные, тестовые) новый разработчик перед тем как пробовать ту или иную конструкцию (например, при оптимизации) может посмотреть историю и выяснить, например, что данная конструкция уже была применена и показала себя неэффективной
  6. Производный от 5, но с метриками.

Представление:
Построим одно дополнительное представление, в которое попадут только измененные файлы. То есть файлы, которые были в первом релизе, но изменились ко второму. Новые файлы и неизмененные файлы ОТОБРАЖАТЬСЯ не должны

5. «Бантики»

Одна из собираемых метрик – LOC по проекту. Сделаем еще лучше: будем вычислять ее по каталогам (то есть будет суммироваться общее число строк для файлов, размещенных в каталоге).

В зависимости от структуры репозитория (например, каждая папка – подсистема) можем получать достаточно продвинутые отчеты.

Суть «бантика» – показать, как встраиваются новые функции в ClearCase.

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

3.3 Реализация требований в IBM Rational ClearCase

Все скрипты написаны на языке Perl, встроенном в ClearCase, прокомментированы и выделены серым цветом

Реализация пунктов 1 и 2: выбор метрик и определение способа хранения

Первый шаг – создание атрибутов. Атрибуты создаются как в графической оболочке так и через команды командной строки. Выбираем наиболее быстрый способ – командную строку.
Листинг

# Определяем наименование репозитория ClearCase (в качестве репозитория выбирается либо компонентный VOB для UCM, либо обычный для Base ClearCase)$repository=»vvv»;

# Определяем все типы атрибутов, необходимых для нашей работы

system(«cleartool.exe mkattype -c \»Number of modules\» -vtype integer cmc_NOM@\\$repository»);

system(«cleartool.exe mkattype -c \»Lines of Code\» -vtype integer cmc_LOC@\\$repository»);

system(«cleartool.exe mkattype -c \»Lines of Comments\» -vtype integer cmc_COM@\\$repository»);

system(«cleartool.exe mkattype -c \»McCabe’s Cyclomatic Complexity\» -vtype integer cmc_MVG@\\$repository»);

system(«cleartool.exe mkattype -c \»Lines of code per line of comment\» -vtype real cmc_L_C@\\$repository»);

system(«cleartool.exe mkattype -c \»Cyclomatic Complexity per line of comment\» -vtype string cmc_M_C@\\$repository»);

Результат работы скрипта – формирование состава атрибутов.

Пример

Рисунок 3 – Вид окна Type Explorer в ClearCase после выполнения операции

3.3.2 Реализация пункта 3: выбор метода сбора информации

У нас нет времени ждать пока сервер посчитает метрики. Пишем и запускаем скрипт сами.

Здесь находится самая интересная особенность. Для подсчета метрик выбрана бесплатная утилита, коих море в сети Интернет. Особенность утилиты в том, что она сканирует только файлы (версии файлов нам надо подставлять скриптом). Результат работы программа записывает в XML файл, который читается, из него извлекаются метрики и показатели и ставятся в виде атрибутов на версии файла.
Листинг

# Используем пакет для работы с XMLuse XML::Simple;

# Формируем запрос к репозиторию на выборку по следующим критериям:

# Только файлы с расширением, начинающимся на  «C»

# На версии файла нет атрибута cmc_LOC (зачем ставить атрибут, если он на версии уже есть

# Эта версия не \main\0, который, как известно, в большинстве случаев ничего в себе не содержит

$arg2=»cleartool find $name -name \»*.c*\» -ver \»!attype(cmc_LOC) && !version(\\main\\0)\» -all -print»;

#Исполняем команду, находящуюся в  массиве. Команда open перехватывает вывод сна консоль

open (FILE, «$arg2 |»);

#Обрабатываем ответ, выводимый командой

while( <FILE> )

{

#Получаем построчно данные из потока и помещаем их в стринговую переменную

chomp;

@_ = split;

$buffer=»@_»;

#Копируем во временный каталог файл, найденный ClearCase, так как система формирования метрик в нынешней редакции не способна работать с динамическими представлениями

system(«copy  $buffer C:\\cmc_scaner\\temp\\temp.cpp»);

#Вызываем внешнее приложение для обработки полученного временного файла с версией исходного текста

system («cccc.exe C:\\cmc_scaner\\temp\\temp.cpp —xml_outfile=c:\\cmc_scaner\\temp\\tmp.xml —outdir=c:\\cmc_scaner\\temp»);

# Читаем XML-файл и заполняем соответствующие переменные

my $cust_xml = XMLin(‘.//temp//tmp.xml’);

$NOM= $cust_xml-> { project_summary } -> { number_of_modules }  -> { value } ;

$LOC= $cust_xml-> { project_summary } -> { lines_of_code }  -> { value } ;

$COM= $cust_xml-> { project_summary } -> { lines_of_comment }  -> { value } ;

$MVG= $cust_xml-> { project_summary } -> { McCabes_cyclomatic_complexity }  -> { value } ;

# Ставим переменные на версию (установка атрибутов)

system(«cleartool.exe mkattr cmc_NOM $NOM $buffer»);

system(«cleartool.exe mkattr cmc_LOC $LOC $buffer»);

system(«cleartool.exe mkattr cmc_COM $COM $buffer»);

system(«cleartool.exe mkattr cmc_MVG $MVG $buffer»);

}

 

 

Пример

Рисунок 4 – Результат работы скрипта на дереве версий одного файла. Обратите внимание на отдельный расчет показателей для различных ответвлений и то, что расчет сделан как для основных релизов (помеченных метками), так и для промежуточных версий.

 

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

В зависимости от того, как настроена политика ветвления (по заказчикам, по субподрядчикам и т.д) можно получать довольно любопытные показатели: например, после приемки кода от субподрядчика провести анализ изменений. Либо построить срез по тому, что было реализовано в конкретной версии.

 

3.3.3 Реализация пункта 4: определение способа представления

1. Количественный состав изменений второго релиза по отношению к первому (какие именно файлы и каких версий были в первом релизе и какими стали во втором). Здесь мы получаем количество промежуточных версий и список измененных файлов.

Пример реализации:
Команда

cleartool.exe find . -element «{lbtype_sub(REL1.0) && lbtype_sub(REL2.0) && !eltype(directory)}» -version «{(lbtype(REL1.0) && !lbtype(REL2.0)) || (lbtype(REL2.0) && !lbtype(REL1.0))}» -all -print

Результат

M:\development\vvv\hello\hello.cpp@@\main\2M:\development\vvv\hello\hello.cpp@@\main\3

M:\development\vvv\hello\ReadMe.txt@@\main\2

M:\development\vvv\hello\ReadMe.txt@@\main\3

M:\development\vvv\cccc\cccc_prj.cc@@\main\1

M:\development\vvv\cccc\cccc_prj.cc@@\main\2

M:\development\vvv\cccc\cccc_xml.cc@@\main\1

M:\development\vvv\cccc\cccc_xml.cc@@\main\2

Отчет как раз показывает версии измененных файлов.

2. Является производным от первого. Все тоже самое + отображение метрик для каждой версии (понимаем объем изменений)
Команда

cleartool.exe find . -element «{lbtype_sub(REL1.0) && lbtype_sub(REL2.0) && !eltype(directory)}» -version «{(lbtype(REL1.0) && !lbtype(REL2.0)) || (lbtype(REL2.0) && !lbtype(REL1.0))}» -all -exec «cleartool descr -fmt «%n\t%[cmc_LOC]a\t%[cmc_COM]a\n» %CLEARCASE_XPN%»

Результат

M:\development\vvv\hello\hello.cpp@@\main\2     (cmc_LOC=5)     (cmc_COM=2)M:\development\vvv\hello\hello.cpp@@\main\3     (cmc_LOC=5)     (cmc_COM=2)

M:\development\vvv\hello\ReadMe.txt@@\main\2

M:\development\vvv\hello\ReadMe.txt@@\main\3

M:\development\vvv\cccc\cccc_prj.cc@@\main\1    (cmc_LOC=313)   (cmc_COM=38)

M:\development\vvv\cccc\cccc_prj.cc@@\main\2    (cmc_LOC=314)   (cmc_COM=42)

M:\development\vvv\cccc\cccc_xml.cc@@\main\1    (cmc_LOC=656)   (cmc_COM=82)

M:\development\vvv\cccc\cccc_xml.cc@@\main\2    (cmc_LOC=669)   (cmc_COM=84)

Обратите внимание на атрибуты LOC и COM.

3. Состав изменений (список измененных файлов с метриками)
Команда

cleartool.exe find . -element «{!eltype(directory)}» -version «{(lbtype(REL2.0) && !lbtype(REL1.0))}» -all -exec «cleartool descr -fmt «%n\t%[cmc_LOC]a\t%[cmc_COM]a\n» %CLEARCASE_XPN%»

Результат

M:\development\vvv\hello\hello.cpp@@\main\3     (cmc_LOC=5)     (cmc_COM=2)M:\development\vvv\hello\ReadMe.txt@@\main\3

M:\development\vvv\cccc\cccc_prj.cc@@\main\2    (cmc_LOC=314)   (cmc_COM=42)

M:\development\vvv\cccc\cccc_xml.cc@@\main\2    (cmc_LOC=669)   (cmc_COM=84)

4. Суть проведенных изменений (какие строки в каких модулях были изменены). Информацию представляем с включенными фрагментами кода
Команда

cleartool.exe find . -element «{!eltype(directory)}» -version «{(lbtype(REL2.0) && !lbtype(REL1.0))}» -all -exec «cleartool diff %CLEARCASE_PN%@@\REL1.0 %CLEARCASE_XPN%»

Результат

**********************<<< file 1: M:\development\vvv\hello\hello.cpp@@\REL1.0

>>> file 2: M:\development\vvv\hello\hello.cpp@@\main\3

********************************

————-[changed 8]—————|————-[changed to 8]————

printf(«Hello World!\n»);     +|         printf(«Гуд бай\n»);+

-|-

********************************

<<< file 1: M:\development\vvv\hello\ReadMe.txt@@\REL1.0

>>> file 2: M:\development\vvv\hello\ReadMe.txt@@\main\3

********************************

—————[after 2]—————-|—————[inserted 3]————-

-|            Релиз2+

|-

********************************

<<< file 1: M:\development\vvv\cccc\cccc_prj.cc@@\REL1.0

>>> file 2: M:\development\vvv\cccc\cccc_prj.cc@@\main\2

********************************

————-[changed 4]—————|————[changed to 4-7]————

+| sd+

-| asd+

| as+

| da+

|-

—————[after 71]—————|————[inserted 75-76]————

-| //Добавлена строка и комментарий+

| lookup_module_ptr->extent_table.find_o+

|-

********************************

<<< file 1: M:\development\vvv\cccc\cccc_xml.cc@@\REL1.0

>>> file 2: M:\development\vvv\cccc\cccc_xml.cc@@\main\2

********************************

—————[after 9]—————-|————[inserted 10-11]————

-|         REL2+

| +

|-

—————[after 87]—————|————[inserted 90-103]————

-| +

| static const string XML_PREAMBLE = «<?+

| static const string XML_COMMENT_BEGIN +

| static const string XML_COMMENT_END = +

| static const string XML_TAG_OPEN_BEGIN+

| static const string XML_TAG_OPEN_END =+

| static const string XML_TAG_CLOSE_BEGI+

| static const string XML_TAG_CLOSE_END +

| static const string XML_TAG_INLINE_BEG+

| static const string XML_TAG_INLINE_END+

| static const string XML_SPACE         +

| static const string XML_NEWLINE       +

| static const string XML_DQUOTE        +

| static const string XML_EQUALS        +

|-

Обратите внимание на указываемые типы изменений (inserted, after, changed).

5. Отчет обо всех изменениях в файле, с указанием кто, когда и какую конструкцию вносил в файл. Отдельно хочется отметить данный отчет, так как он позволяет каждому новому разработчику анализировать свой модуль на все изменения и получать единым отчетом информацию о его корректировке, что позволяет СУЩЕСТВЕННО экономить время при анализе кода.
Команда

clt ann -all -long hello.cpp

Результат

M:\development\vvv\hello\hello.cpp—————04-ноя-07.00:55:39 ##### alex (alex.None@ware) \main\6Добавление комментария для улучшения показателей—————

17-окт-07.12:12:54 ####  alex (alex.None@ware) \main\5

—————

17-окт-07.12:09:14 ####  alex (alex.None@ware) \main\4 (rel3.0)

Добавление строки

—————

15-авг-07.14:23:46 ###   alex (alex.None@ware) \main\REL2.0bugfix\2

—————

15-авг-07.14:22:39 ###   alex (alex.None@ware) \main\REL2.0bugfix\NAN\1

xczxcz

—————

15-авг-07.14:22:06 ###   alex (alex.None@ware) \main\REL2.0bugfix\NAN\0

—————

15-авг-07.14:18:45 ###   alex (alex.None@ware) \main\REL2.0bugfix\1

—————

15-авг-07.14:18:32 ###   alex (alex.None@ware) \main\REL2.0bugfix\0

—————

15-авг-07.14:12:47 ###   alex (alex.None@ware) \main\REL1.0bugfix\2

—————

15-авг-07.14:10:41 ###   alex (alex.None@ware) \main\REL1.0bugfix\1

—————

15-авг-07.14:10:24 ###   alex (alex.None@ware) \main\REL1.0bugfix\0

—————

15-авг-07.10:13:22 ###   alex (alex.None@ware) \main\3 (REL2.0)

Добавлено прощание

—————

15-авг-07.10:12:13 ###   alex (alex.None@ware) \main\2 (REL1.0)

—————

15-авг-07.10:11:43 ###   alex (alex.None@ware) \main\1

—————

15-авг-07.10:11:43 ###   alex (alex.None@ware) \main\0

—————

————————————————-

————————————————-

###   15-авг-07.10:11:43 alex     \main\1                  |                        | // hello.cpp : Defines the entry point for the console application.

###                           .                            |                        | //

###   15-авг-07.14:23:46 alex     \main\REL2.0bugfix\2     | UNRELATED              | //

###   15-авг-07.14:22:39 alex     \main\REL2.0bugfix\NAN\1 | UNRELATED              | //

###   15-авг-07.10:11:43 alex     \main\1                  |                        |

###                           .                            |                        | #include «stdafx.h»

###                           .                            |                        |

###                           .                            |                        | int main(int argc, char* argv[])

###                           .                            |                        | {

##### 04-ноя-07.00:55:39 alex     \main\6                  |                        |         // Строка комментария

###   15-авг-07.10:11:43 alex     \main\1                  | DEL 15-авг-07 alex     |         printf(«Hello World!\n»);

###   15-авг-07.14:10:41 alex     \main\REL1.0bugfix\1     | UNRELATED              |         // Комментарий для фикса баги

###   15-авг-07.14:12:47 alex     \main\REL1.0bugfix\2     | UNRELATED              |         // dfdf

###   15-авг-07.10:13:22 alex     \main\3                  |                        |         printf(«Гуд бай\n»);

####  17-окт-07.12:09:14 alex     \main\4                  |                        |         printf(«еще чегото делаю\n»);

##### 04-ноя-07.00:55:39 alex     \main\6                  |                        |         printf(«Новая сторка\n»);

###   15-авг-07.14:18:45 alex     \main\REL2.0bugfix\1     | UNRELATED              |         printf(«Гуд бай для заказчика\n»);

###   15-авг-07.10:11:43 alex     \main\1                  |                        |         return 0;

###                           .                            |                        | }

###                           .                            |                        |

6. Производный от 5, но с метриками.
Команда

clt ann -all  -fmt «%d %[cmc_LOC]a %[cmc_COM]a » hello.cpp

Результат

M:\development\vvv\hello\hello.cpp—————04-ноя-07 alex       \main\6Добавление комментария для улучшения показателей———

17-окт-07 alex       \main\5

———

17-окт-07 alex       \main\4 (rel3.0)

Добавление строки

———

15-авг-07 alex       \main\REL2.0bugfix\2

———

15-авг-07 alex       \main\REL2.0bugfix\NAN\1

xczxcz

———

15-авг-07 alex       \main\REL2.0bugfix\NAN\0

———

15-авг-07 alex       \main\REL2.0bugfix\1

———

15-авг-07 alex       \main\REL2.0bugfix\0

———

15-авг-07 alex       \main\REL1.0bugfix\2

———

15-авг-07 alex       \main\REL1.0bugfix\1

———

15-авг-07 alex       \main\REL1.0bugfix\0

———

15-авг-07 alex       \main\3 (REL2.0)

Добавлено прощание

———

15-авг-07 alex       \main\2 (REL1.0)

———

15-авг-07 alex       \main\1

———

15-авг-07 alex       \main\0

———

————————————————-

————————————————-

15-авг-07.10:11:43 (cmc_LOC=5) (cmc_COM=2)                        | // hello.cpp : Defines the entry point for the console application.

.                                            | //

15-авг-07.14:23:46 (cmc_LOC=5) (cmc_COM=3) UNRELATED              | //

15-авг-07.14:22:39   UNRELATED              | //

15-авг-07.10:11:43 (cmc_LOC=5) (cmc_COM=2)                        |

.                                            | #include «stdafx.h»

.                                            |

.                                            | int main(int argc, char* argv[])

.                                            | {

04-ноя-07.00:55:39 (cmc_LOC=7) (cmc_COM=3)                        |         // Строка комментария

15-авг-07.10:11:43 (cmc_LOC=5) (cmc_COM=2) DEL 15-авг-07 alex     |         printf(«Hello World!\n»);

15-авг-07.14:10:41 (cmc_LOC=5) (cmc_COM=3) UNRELATED              |         // Комментарий для фикса баги

15-авг-07.14:12:47 (cmc_LOC=5) (cmc_COM=4) UNRELATED              |         // dfdf

15-авг-07.10:13:22 (cmc_LOC=5) (cmc_COM=2)                        |         printf(«Гуд бай\n»);

17-окт-07.12:09:14 (cmc_LOC=6) (cmc_COM=2)                        |         printf(«еще чегото делаю\n»);

04-ноя-07.00:55:39 (cmc_LOC=7) (cmc_COM=3)                        |         printf(«Новая сторка\n»);

15-авг-07.14:18:45 (cmc_LOC=5) (cmc_COM=2) UNRELATED              |         printf(«Гуд бай для заказчика\n»);

15-авг-07.10:11:43 (cmc_LOC=5) (cmc_COM=2)                        |         return 0;

.                                            | }

.                                            |

Формирование представления

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

Предварительно посмотрим скриншот ClearCase Explorer для простого представления, в котором собраны последние версии файлов.

список файлов

Рисунок 5 – Общий список файлов

Как видим, нам представлен общий список файлов.

Создаем представление с такой конфигурационной спецификацией:
Листинг

element * CHECKEDOUTelement -directory * /main/LATEST

element * {(lbtype(REL2.0)&&!lbtype(REL1.0))}

Листинг

Рисунок 6 – результат работы после применения фильтра

3.3.4 Реализация пункта 5: «бантики». Формирование контекстного меню и подсчет метрики LOC для подсистем и проекта в целом

ClearCase имеет возможности по созданию пунктов контекстного меню для встроенного Explorer и для Windows Explorer.

Наша цель, для реализации пункта 5 сформировать скрипт, проводящий подсчет атрибутов в заданном каталоге
Листинг

$arg = shift @ARGV;$arg2=»cleartool ls -s -r -vis $arg»;

#Исполняем команду, находящуюся в  массиве. Команда open перехватывает вывод сна консоль

open (FILE, «$arg2 |»);

# Инициализируем переменные

$total=1;

$total_with_attr=1;

$sum_LOC=0;

#Обрабатываем ответ, выводимый командой

while( <FILE> )

{

#Получаем построчно данные из потока и помещаем их в стринговую переменную

chomp;

@_ = split;

$buffer=»@_»;

# Подаем команду получения свойств объекта. Из свойств нас интересует только атрибут, указывающий на метрик Lines Of Code

open (FILE1, «clt descr -fmt \»%[cmc_LOC]a\» $buffer |»);

#Получаем построчно данные из потока и помещаем их в стринговую переменную

while( <FILE1> )

{

#Получаем построчно данные из потока и помещаем их в стринговую переменную

chomp;

@_ = split;

$buffer2=»@_»;

# Отсекаем все лишнее

@str_new_scr=split(‘[=)<<,\'\>]‘,$buffer2);

# Увеличиваем счетчик на единицу и суммируем результат

$sum_LOC=$sum_LOC+$str_new_scr[1];

$total_with_attr=$total_with_attr+1;

}

$total=$total+1;

}

# Выводим среднее арифметическое

$tt=$sum_LOC/$total_with_attr;

# Конкатенируем полученныеданные и представляем их на экране с использованием штатной утилиты ClearCase

$outt = «Total files — $total\n Files with LOC attribute — $total_with_attr\n\n Sumary LOC in files — $sum_LOC\n Average — $tt»;

$ent = system(«clearprompt proceed -prompt \»$outt \»  -mask abort -prefer_gui «);

В модуле создания контекстных меню формируем пункт для директорий и ссылаемся на скрипт. В аргументах передаем путь до текущего каталога.

Программирование контекстного меню

Рисунок 7 – Программирование контекстного меню ClearCase

После выполнения манипуляций пункт «calculate» появится на каталогах, хранимых в репозитории.

Вызов контекстного меню

Рисунок 8 – Вызов контекстного меню на имени каталог. Ожидаемый результат: сканирование всех файлов и подсчет метрик

Активация пункта приведет к вызову скрипта и к выводу следующего окна на экран.

 

 

Результат подсчета

Рисунок 9 – Результат подсчета

 

4. Заключение

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

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

Для более подробного ознакомления с IBM Rational ClearCase смотрите также:

5. Литература

  1. The Build Master. Microsoft Software Configuration Management Best Practices
  2. Steven C.McConnell «Code Complete», 2nd. Ed.
  3. IEEE Std 1058-1998, Standard for Software Project Management Plans.
  4. IEEE Std 12207-1997, Information Technology—Software Life Cycle Processes.
  5. IEEE Std 1045-1992, Standard for Software Productivity Metrics.
  6. IEEE Std 1062-1998, Recommended Practice for Software Acquisition.
  7. IEEE Std 1540-2001, Standard for Software Life Cycle Processes—Risk Management.
  8. IEEE Std 828-1998, Standard for Software Configuration Management Plans
  9. IEEE Std 1490-1998, Guide—Adoption of PMI Standard—A Guide to the Project Management Body of Knowledge
  10. ГОСТ Р ИСО/МЭК ТО 16326-2002. Программная инженерия. Руководство по применению ГОСТ Р ИСО/МЭК 12207 при управлении проектом.
  11. Изосимов А.В., Рыжко А.Л. Метрическая оценка качества программ. — М.: МАИ, 1989.
  12. Холстед М. Начала науки о программах. — М.: Финансы и статистика, 1981.
  13. Вячеслав Колдовский, Разработка ПО: метрики программных проектов
  14. Oviedo E.J. Control flow, data flow and program complexity. — Proc. IEEE COMPSAC. — Chicago, IL, Nov. 1980. — pp. 146-152.

6. Ресурсы интернет, используемые в статье

Описание командной строки IBM Rational ClearCase

Утилита, используемая в примерах — http://cccc.sourceforge.net/

http://www.giac.unibel.by/docs/pdf/1-2005/s10-1-2005.pdf

http://www.cs.umd.edu/~basili/papers.html

http://msquaredtechnologies.com/m2rsm/

http://www.aivosto.com/project/help/pm-loc.html

http://kapustin-andrey.boom.ru/Materials/Metrics2.htm

http://kapustin-andrey.boom.ru/Materials/Metrics1.htm

http://www.met-rix.narod.ru/index.htm

http://www.maxkir.com/sd/newmethRUS.html

http://www.optim.su/cs/2003/4/AOP2/AOP.asp

http://www.mstandard.ru/certification/03/

http://www.virtualmachinery.com/jhawkmetrics.htm

http://msquaredtechnologies.com/m2rsm/docs/cyclocomplex/cyclo_1.htm

Метрики кода и их практическая реализация в IBM Rational ClearCase, 10.0 out of 10 based on 2 ratings
Стационарные автомойки "ИнВестСтрой"..

Связные и просто интересные записи:

Метки:clearcase, ibm, loc, rational, sloc, джилб, код, маккейб, метрики, программа, программирование, сложность, цикломатичность, чепин

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Spam protection by WP Captcha-Free