Количество ошибок на количество строк кода

Насколько сложный программный код у Windows и как он менялся?

Чтобы разобраться вопросе, насколько может быть сложным программный код «Виндовс» мы обратились к одному из разработчиков команды Windows NT в компании Microsoft — Кену Греггу (Ken Gregg).

Кен Грегг (Ken Gregg), разработчик в составе группы Windows NT

«Могу сказать вам, что у меня был доступ к исходному коду, когда я был в команде Windows NT (NT является основой для всех настольных версий Windows начиная с XP), во время проектов разработки NT 3.1 и NT 3.5. Всё было в рамках стандартов кодирования NT Workbook — эдакой «библии» для всей проектной команды.

. Хотя я и не читал каждую строку кода, но то, с чем мне пришлось работать, было очень:

Нужно исходить из того, что именно понимается под сложностью кода. Это понимание сугубо субъективное, ведь так? Благо существует множество различных метрик, используемых и комбинируемых для измерения сложности программного обеспечения в тех или иных ситуациях (та же самая модульность, многоуровневость и обслуживаемость).

Насколько сложна Windows в программном коде?

Конечно, чтобы прочитать и понять код, вам нужно было бы иметь представление об общей архитектуре Windows NT.

Вероятно, лучшим источником информации о внутренностях Windows сегодня являются книги Windows Internals 6th Edition (в двух томах).

Некоторые люди просто приравнивают сложность кода к размеру. У этого сравнения тоже есть метрика — строки кода (LOC).

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

Насколько сложный программный код у Windows и как он менялся?

Кен Грегг (Ken Gregg)

«Существует много споров о методах, используемых для подсчета строк кода (LOC). Если использовать одни и те же критерии от одного выпуска к следующему, то получится относительное изменение размера базы кода.

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

Как менялся программный код Windows?

Как база кода Windows NT развивалась с 1993 года

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

Исходный код Windows состоит в основном из C и C++, а также небольшого количества кода на ассемблере.

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

Насколько сложный программный код у Windows и как он менялся?

Кен Грегг (Ken Gregg)

«Я намеренно не включил в список 16-битные версии ОС, выпущенные с 1985 по 2000 годы. Windows NT была основой для всех современных 32-бит и 64-бит версий Windows. Количество строк кода в серверных версиях было таким же, как и в несерверных версиях, выпущенных в том же году (то есть они имели одинаковую базу исходного кода)».

Несколько слов про ядро Windows NT

По словам Кена, работа над ядром NT началась в 1988 году. Ядро было создано с нуля в качестве 32-разрядной упреждающей многозадачной ОС.

Ядро NT впервые загрузилось в июле 1989 года на процессоре Intel i860 RISC. С самого начала был сильный толчок к тому, чтобы новая ОС была совместимой с различными архитектурами центральных процессоров и не была привязана только к архитектуре Intel x86 (IA-32).

NT в конечном итоге работал на MIPS, DEC Alpha, PowerPC, Itanium и, конечно, Intel x86 и x64.

Некоторая сложность была добавлена в базу кода на уровне абстрагирования оборудования (HAL). Это было нужно для поддержки неинтеловских архитектур.

А как вы оцениваете перспективы Windows в плане кода? Узнайте, какие версии Windows актуальны сейчас и какие ОС можно рассмотреть в качестве альтернативы.

Есть проблемы при использовании Windows и непонятен программный код для внедрения новых бизнес-инструментов в ОС от Microsoft? Проконсультируйтесь с экспертами по ИТ-аутсорсингу и получите поддержку по любым техническим вопросам и задачам.

Помехоустойчивое кодирование. Коды Хэмминга

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

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

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

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

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

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

Исправление ошибок в помехоустойчивом кодировании

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

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

Допустим есть 4 символа информации, А, B, С, D, и эту информацию повторяем несколько раз. В процессе передачи информации по каналу связи, где-то возникла ошибка. Есть три пакета (A1B1C1D1|A2B2C2D2|A3B3C3D3), которые должны нести одну и ту же информацию.

мажоритарный метод

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

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

Для исправления ошибок нужно, как минимум 3 пакета информации, для обнаружения, как минимум 2 пакета информации.

Параметры помехоустойчивого кодирования

Первый параметр, скорость кода R характеризует долю информационных («полезных») данных в сообщении и определяется выражением: R=k/n=k/m+k

Параметры n и k часто приводят вместе с наименованием кода для его однозначной идентификации. Например, код Хэмминга (7,4) значит, что на вход кодера приходит 4 символа, на выходе 7 символов, Рида-Соломона (15, 11) и т. д.

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

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

Контроль чётности

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

Если нечетное количество единиц, добавляем 0.

1 0 1 0 0 1 0 0 | 0

Если четное количество единиц, добавляем 1.

1 1 0 1 0 1 0 0 | 1

Если принятый бит чётности не совпадает с рассчитанным битом чётности, то считается, что произошла ошибка.

1 1 0 0 0 1 0 0 | 1

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

Есть последовательность 0 и 1, и из этой последовательности составим прямоугольную матрицу размера 4 на 4. Затем для каждой строки и столбца посчитаем бит четности.

Прямоугольный код – код с контролем четности, позволяющий исправить одну ошибку:

прямоугольный код

И если в процессе передачи информации допустим ошибку (ошибка нолик вместо единицы, желтым цветом), начинаем делать проверку. Нашли ошибку во втором столбце, третьей строке по координатам. Чтобы исправить ошибку, просто инвертируем 1 в 0, тем самым ошибка исправляется.

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

Рассчитаем скорость кода для:

Здесь R=16/24=0,66 (картинка выше, двадцать пятую единичку (бит четности) не учитываем)

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

Классификация помехоустойчивых кодов

По используемому алфавиту:

Блочные коды делятся на

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

систематический и несистематический код

Смотря на картинку выше, код 1 1 0 0 0 1 0 0 | 1 является систематическим, на вход поступило 8 бит, а на выходе кодера 9 бит, которые в явном виде содержат в себе 8 бит информационных и один проверочный.

Классификация помехоустойчивых кодов

Код Хэмминга

Код Хэмминга — наиболее известный из первых самоконтролирующихся и самокорректирующихся кодов. Позволяет устранить одну ошибку и находить двойную.

Код Хэмминга (7,4)

Код Хэмминга (7,4) — 4 бита на входе кодера и 7 на выходе, следовательно 3 проверочных бита. С 1 по 4 информационные биты, с 6 по 7 проверочные (см. табл. выше). Пятый проверочный бит y5, это сумма по модулю два 1-3 информационных бит. Сумма по модулю 2 это вычисление бита чётности.

Декодирование кода Хэмминга

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

Декодирование кода Хэмминга через синдром

Синдром это сложение бит по модулю два. Если синдром не нулевой, то исправление ошибки происходит по таблице декодирования:

Таблица декодирования. Код Хэмминга

Расстояние Хэмминга

Расстояние Хэмминга — число позиций, в которых соответствующие символы двух кодовых слов одинаковой длины различны. Если рассматривать два кодовых слова, (пример на картинке ниже, 1 0 1 1 0 0 1 и 1 0 0 1 1 0 1) видно что они отличаются друг от друга на два символа, соответственно расстояние Хэмминга равно 2.

расстояние хэмминга

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

Помехоустойчивые коды

Современные коды более эффективны по сравнению с рассматриваемыми примерами. В таблице ниже приведены Коды Боуза-Чоудхури-Хоквингема (БЧХ)

Коды Боуза-Чоудхури-Хоквингема (БЧХ)

Из таблицы видим, что там один класс кода БЧХ, но разные параметры n и k.

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

Пример: помехоустойчивые коды и двоичная фазовая манипуляция (2-ФМн). На графике зависимость отношения сигнал шум (Eb/No) от вероятности ошибки. За счет применения помехоустойчивых кодов улучшается помехоустойчивость.

График помехоустойчивых кодов

Из графика видим, код Хэмминга (7,4) на сколько увеличилась помехоустойчивость? Всего на пол Дб это мало, если применить код БЧХ (127, 64) выиграем порядка 4 дБ, это хороший показатель.

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

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

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

Необходимость чередования (перемежения)

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

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

Пример блочного перемежения:

Пример блочного перемежения кодов

На картинке, всего 5 блоков (с 1 по 25). Код работает исправляя ошибки в рамках одного блока (если в одном блоке 1 ошибка, код его исправит, а если две то нет). В канал связи отдается информация не последовательно, а в перемешку. На выходе кодера сформировались 5 блоков и эти 5 блоков будем отдавать не по очереди а в перемешку. Записали всё по строкам, но считывать будем, чтобы отправлять в канал связи, по столбцам. Информация в блоках перемешалась. В канале связи возникла ошибка и мы потеряли большой кусок. В процессе приема, мы опять составляем таблицу, записываем по столбцам, но считываем по строкам. За счет того, что мы перемешали большое количество блоков между собой, групповая ошибка равномерно распределится по блокам.

Источники:

https://www. zeluslugi. ru/info-czentr/stati/programmnyy-kod-windows

https://zvondozvon. ru/radiosvyaz/kody-hemminga

Программный код и его метрики

Время на прочтение
19 мин

Количество просмотров 120K

Измерения...
Одной из тем в программировании, к которым интерес периодически то появляется, то пропадает, является вопрос метрик кода программного обеспечения. В крупных программных средах время от времени появляются механизмы подсчета различных метрик. Волнообразный интерес к теме так выглядит потому, что до сих пор в метриках не придумано главного — что с ними делать. То есть даже если какой-то инструмент позволяет хорошо подсчитать некоторые метрики, то что с этим делать дальше зачастую непонятно. Конечно, метрики — это и контроль качества кода (не пишем большие и сложные функции), и «производительность» (в кавычках) программистов, и скорость развития проекта. Эта статья — обзор наиболее известных метрик кода программного обеспечения.

Введение

В статье приведен обзор 7 классов метрик и более 50 их представителей.

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

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

1. Количественные метрики

Прежде всего, следует рассмотреть количественные характеристики исходного кода программ (в виду их простоты). Самой элементарной метрикой является количество строк кода (SLOC). Данная метрика была изначально разработана для оценки трудозатрат по проекту. Однако из-за того, что одна и та же функциональность может быть разбита на несколько строк или записана в одну строку, метрика стала практически неприменимой с появлением языков, в которых в одну строку может быть записано больше одной команды. Поэтому различают логические и физические строки кода. Логические строки кода — это количество команд программы. Данный вариант описания так же имеет свои недостатки, так как сильно зависит от используемого языка программирования и стиля программирования [2].

Кроме SLOC к количественным характеристикам относят также:

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

Иногда дополнительно различают оценку стилистики программы (F). Она заключается в разбиении программы на n равных фрагментов и вычислении оценки для каждого фрагмента по формуле Fi = SIGN (Nкомм.i / Ni — 0,1), где Nкомм.i — количество комментариев в i-м фрагменте, Ni — общее количество строк кода в i-м фрагменте. Тогда общая оценка для всей программы будет определяться следующим образом: F = СУММА Fi. [2]

Также к группе метрик, основанных на подсчете некоторых единиц в коде программы, относят метрики Холстеда [3]. Данные метрики основаны на следующих показателях:

n1 — число уникальных операторов программы, включая символы-

разделители, имена процедур и знаки операций (словарь операторов),

n2 — число уникальных операндов программы (словарь операндов),

N1 — общее число операторов в программе,

N2 — общее число операндов в программе,

n1′ — теоретическое число уникальных операторов,

n2′ — теоретическое число уникальных операндов.

Учитывая введенные обозначения, можно определить:

n=n1+n2 — словарь программы,

N=N1+N2 — длина программы,

n’=n1’+n2′ — теоретический словарь программы,

N’= n1*log2(n1) + n2*log2(n2) — теоретическая длина программы (для стилистически корректных программ отклонение N от N’ не превышает 10%)

V=N*log2n — объем программы,

V’=N’*log2n’ — теоретический объем программы, где n* — теоретический словарь программы.

L=V’/V — уровень качества программирования, для идеальной программы L=1

L’= (2 n2)/ (n1*N2) — уровень качества программирования, основанный лишь на параметрах реальной программы без учета теоретических параметров,

EC=V/(L’)2 — сложность понимания программы,

D=1/ L’ — трудоемкость кодирования программы,

y’ = V/ D2 — уровень языка выражения

I=V/D — информационное содержание программы, данная характеристика позволяет определить умственные затраты на создание программы

E=N’ * log2(n/L) — оценка необходимых интеллектуальных усилий при разработке программы, характеризующая число требуемых элементарных решений при написании программы

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

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

2. Метрики сложности потока управления программы

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

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

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

Самой распространенной оценкой, основанной на анализе получившегося графа, является цикломатическая сложность программы (цикломатическое число Мак-Кейба) [4]. Она определяется как V(G)=e — n + 2p, где e — количество дуг, n — количество вершин, p — число компонент связности. Число компонентов связности графа можно рассматривать как количество дуг, которые необходимо добавить для преобразования графа в сильно связный. Сильно связным называется граф, любые две вершины которого взаимно достижимы. Для графов корректных программ, т. е. графов, не имеющих недостижимых от точки входа участков и «висячих» точек входа и выхода, сильно связный граф, как правило, получается путем замыкания дугой вершины, обозначающей конец программы, на вершину, обозначающую точку входа в эту программу. По сути V(G) определяет число линейно независимых контуров в сильно связном графе. Так что в корректно написанных программах p=1, и поэтому формула для расчета цикломатической сложности приобретает вид:

V(G)=e — n + 2.

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

Для исправления данного недостатка Г. Майерсом была разработана новая методика. В качестве оценки он предложил взять интервал (эта оценка еще называется интервальной) [V(G),V(G)+h], где h для простых предикатов равно нулю, а для n-местных h=n-1. Данный метод позволяет различать разные по сложности предикаты, однако на практике он почти не применяется.

Еще одна модификация метода Мак-Кейба — метод Хансена. Мера сложности программы в данном случае представляется в виде пары (цикломатическая сложность, число операторов). Преимуществом данной меры является ее чувствительность к структурированности ПО.

Топологическая мера Чена выражает сложность программы через число пересечений границ между областями, образуемыми графом программы. Этот подход применим только к структурированным программам, допускающим лишь последовательное соединение управляющих конструкций. Для неструктурированных программ мера Чена существенно зависит от условных и безусловных переходов. В этом случае можно указать верхнюю и нижнюю границы меры. Верхняя — есть m+1, где m — число логических операторов при их взаимной вложенности. Нижняя — равна 2. Когда управляющий граф программы имеет только одну компоненту связности, мера Чена совпадает с цикломатической мерой Мак-Кейба.

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

Данные меры учитывает уровень вложенности и протяженность программы.

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

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

Функциональная мера (SCOPE) программы — это сумма приведенных сложностей всех вершин управляющего графа.

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

SCORT может принимать разные значения для графов с одинаковым цикломатическим числом.

Метрика Пивоварского — очередная модификация меры цикломатической сложности. Она позволяет отслеживать различия не только между последовательными и вложенными управляющими конструкциями, но и между структурированными и неструктурированными программами. Она выражается отношением N(G) = v *(G) + СУММАPi, где v *(G) — модифицированная цикломатическая сложность, вычисленная так же, как и V(G), но с одним отличием: оператор CASE с n выходами рассматривается как один логический оператор, а не как n — 1 операторов.

Рi — глубина вложенности i-й предикатной вершины. Для подсчета глубины вложенности предикатных вершин используется число «сфер влияния». Под глубиной вложенности понимается число всех «сфер влияния» предикатов, которые либо полностью содержатся в сфере рассматриваемой вершины, либо пересекаются с ней. Глубина вложенности увеличивается за счет вложенности не самих предикатов, а «сфер влияния». Мера Пивоварского возрастает при переходе от последовательных программ к вложенным и далее к неструктурированным, что является ее огромным преимуществом перед многими другими мерами данной группы.

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

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

Пусть G — управляющий граф программы с единственной начальной и единственной конечной вершинами.

В этом графе число входящих вершин у дуг называется отрицательной степенью вершины, а число исходящих из вершины дуг — положительной степенью вершины. Тогда набор вершин графа можно разбить на две группы: вершины, у которых положительная степень <=1; вершины, у которых положительная степень >=2.

Вершины первой группы назовем принимающими вершинами, а вершины второй группы — вершинами отбора.

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

S0=1-(v-1)/Sa,

где S0 — относительная граничная сложность программы, Sa — абсолютная граничная сложность программы, v — общее число вершин графа программы.

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

3. Метрики сложности потока управления данными

Следующий класс метрик — метрики сложности потока управления данных.

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

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

1. P — вводимые переменные для расчетов и для обеспечения вывода,

2. M — модифицируемые, или создаваемые внутри программы переменные,

3. C — переменные, участвующие в управлении работой программного модуля (управляющие переменные),

4. T — не используемые в программе («паразитные») переменные.

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

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

Q = a1*P + a2*M + a3*C + a4*T,

где a1, a2, a3, a4 — весовые коэффициенты.

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

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

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

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

Пара «модуль-глобальная переменная» обозначается как (p,r), где p — модуль, имеющий доступ к глобальной переменной r. В зависимости от наличия в программе реального обращения к переменной r формируются два типа пар «модуль — глобальная переменная»: фактические и возможные. Возможное обращение к r с помощью p показывает, что область существования r включает в себя p.

Данная характеристика обозначается Aup и говорит о том, сколько раз модули Up действительно получали доступ к глобальным переменным, а число Pup — сколько раз они могли бы получить доступ.

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

Rup = Aup/Pup.

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

На основе концепции информационных потоков создана мера Кафура. Для использования данной меры вводятся понятия локального и глобального потока: локальный поток информации из A в B существует, если:

1. Модуль А вызывает модуль В (прямой локальный поток)

2. Модуль В вызывает модуль А и А возвращает В значение, которое используется в В (непрямой локальный поток)

3. Модуль С вызывает модули А, В и передаёт результат выполнения модуля А в В.

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

На основе этих понятий вводится величина I — информационная сложность процедуры:
I = length * (fan_in * fan_out)2
Здесь:

length — сложность текста процедуры (меряется через какую-нибудь из метрик объёма, типа метрик Холстеда, Маккейба, LOC и т.п.)

fan_in — число локальных потоков входящих внутрь процедуры плюс число структур данных, из которых процедура берёт информацию

fan_out — число локальных потоков исходящих из процедуры плюс число структур данных, которые обновляются процедурой

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

Следующий шаг — рассмотреть информационную сложность модуля относительно некоторой структуры данных. Информационная мера сложности модуля относительно структуры данных:

J = W * R + W * RW + RW *R + RW * (RW — 1)

W — число процедур, которые только обновляют структуру данных;

R — только читают информацию из структуры данных;

RW — и читают, и обновляют информацию в структуре данных.

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

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

Обозначим через R(i) множество определяющих вхождений переменных, которые расположены в радиусе действия луча i (определяющее вхождение переменной находится в радиусе действия луча, если переменная либо локальна в нём и имеет определяющее вхождение, либо для неё есть определяющее вхождение в некотором предшествующем луче, и нет локального определения по пути). Обозначим через V(i) множество переменных, использующие вхождения которых уже есть в луче i. Тогда мера сложности i-го луча задаётся как:

DF(i)=СУММА(DEF(vj)), j=i…||V(i)||

где DEF(vj) — число определяющих вхождений переменной vj из множества R(i), а ||V(i)|| — мощность множества V(i).

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

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

Первой из таких метрик является тестирующая М-Мера [5]. Тестирующей мерой М называется мера сложности, удовлетворяющая следующим условиям:

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

Также мерой качества программного обеспечения служит связанность модулей программы [6]. Если модули сильно связанны, то программа становится трудномодифицируемой и тяжелой в понимании. Данная мера не выражается численно. Виды связанности модулей:

Связанность по данным — если модули взаимодействуют через передачу параметров и при этом каждый параметр является элементарным информационным объектом. Это наиболее предпочтительный тип связанности (сцепления).

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

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

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

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

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

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

Отсутствие связанности — модули не взаимодействуют между собой.

Подклассовая связанность — отношение между классом-родителем и классом-потомком, причем потомок связан с родителем, а родитель с потомком — нет.

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

Еще одна мера, касающаяся стабильности модуля — мера Колофелло [7], она может быть определена как количество изменений, которые требуется произвести в модулях, отличных от модуля, стабильность которого проверяется, при этом эти изменения должны касаться проверяемого модуля.

Следующая метрика из данного класса — Метрика Мак-Клура. Выделяются три этапа вычисления данной метрики:

1. Для каждой управляющей переменной i вычисляется значениt её сложностной функции C(i) по формуле: C(i) = (D(i) * J(i))/n.

Где D(i) — величина, измеряющая сферу действия переменной i. J(i) — мера сложности взаимодействия модулей через переменную i, n — число отдельных модулей в схеме разбиения.

2. Для всех модулей, входящих в сферу разбиения, определяется значение их сложностных функций M(P) по формуле M(P) = fp * X(P) + gp * Y(P)
где fp и gp — соответственно, число модулей, непосредственно предшествующих и непосредственно следующих за модулем P, X(P) — сложность обращения к модулю P,

Y(P) — сложность управления вызовом из модуля P других модулей.

3. Общая сложность MP иерархической схемы разбиения программы на модули задаётся формулой:

MP = СУММА(M(P)) по всем возможным значениям P — модулям программы.

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

Также существует метрика, основанная на информационной концепции — мера Берлингера [8]. Мера сложности вычисляется как M=СУММАfi*log2pi, где fi — частота появления i-го символа, pi — вероятность его появления.

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

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

В связи с развитием объектно-ориентированных языков программирования появился новый класс метрик, также называемый объектно-ориентированными метриками. В данной группе наиболее часто используемыми являются наборы метрик Мартина и набор метрик Чидамбера и Кемерера. Для начала рассмотрим первую подгруппу.

Прежде чем начать рассмотрение метрик Мартина необходимо ввести понятие категории классов [9]. В реальности класс может достаточно редко быть повторно использован изолированно от других классов. Практически каждый класс имеет группу классов, с которыми он работает в кооперации, и от которых он не может быть легко отделен. Для повторного использования таких классов необходимо повторно использовать всю группу классов. Такая группа классов сильно связна и называется категорией классов. Для существования категории классов существуют следующие условия:

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

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

Классы в категории разделяют некоторую общую функцию или достигают некоторой общей цели.

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

1. Ca: Центростремительное сцепление. Количество классов вне этой категории, которые зависят от классов внутри этой категории.

2. Ce: Центробежное сцепление. Количество классов внутри этой категории, которые зависят от классов вне этой категории.

3. I: Нестабильность: I = Ce / (Ca+Ce). Эта метрика имеет диапазон значений [0,1].

I = 0 указывает максимально стабильную категорию.

I = 1 указывает максимально не стабильную категорию.

Можно определять метрику, которая измеряет абстрактность (если категория абстрактна, то она достаточно гибкая и может быть легко расширена) категории следующим образом:

A: Абстрактность: A = nA / nAll.

nA — количество_абстрактных_классов_в_категории.

nAll — oбщее_количество_классов_в_категории.

Значения этой метрики меняются в диапазоне [0,1].

0 = категория полностью конкретна,

1 = категория полностью абстрактна.

Теперь на основе приведенных метрик Мартина можно построить график, на котором отражена зависимость между абстрактностью и нестабильностью. Если на нем построить прямую, задаваемую формулой I+A=1, то на этой прямой будут лежать категории, имеющие наилучшую сбалансированность между абстрактностью и нестабильностью. Эта прямая называется главной последовательностью.

Далее можно ввести еще 2 метрики:

Расстояние до главной последовательности: D=|(A+I-1)/sqrt(2)|

Нормализированной расстояние до главной последовательности: Dn=|A+I-2|

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

Следующая подгруппа метрик — метрики Чидамбера и Кемерера [10]. Эти метрики основаны на анализе методов класса, дерева наследования и т.д.

WMC (Weighted methods per class), суммарная сложность всех методов класса: WMC=СУММАci, i=1…n, где ci — сложность i-го метода, вычисленная по какой либо из метрик (Холстеда и т.д. в зависимости от интересующего критерия), если у всех методов сложность одинаковая, то WMC=n.

DIT (Depth of Inheritance tree) — глубина дерева наследования (наибольший путь по иерархии классов к данному классу от класса-предка), чем больше, тем лучше, так как при большей глубине увеличивается абстракция данных, уменьшается насыщенность класса методами, однако при достаточно большой глубине сильно возрастает сложность понимания и написания программы.

NOC (Number of children) — количество потомков (непосредственных), чем больше, тем выше абстракция данных.

CBO (Coupling between object classes) — сцепление между классами, показывает количество классов, с которыми связан исходный класс. Для данной метрики справедливы все утверждения, введенные ранее для связанности модулей, то есть при высоком CBO уменьшается абстракция данных и затрудняется повторное использование класса.

RFC (Response for a class) — RFC=|RS|, где RS — ответное множество класса, то есть множество методов, которые могут быть потенциально вызваны методом класса в ответ на данные, полученные объектом класса. То есть RS=(({M}({Ri}), i=1…n, где M — все возможные методы класса, Ri — все возможные методы, которые могут быть вызваны i-м классом. Тогда RFC будет являться мощностью данного множества. Чем больше RFC, тем сложнее тестирование и отладка.

LCOM (Lack of cohesion in Methods) — недостаток сцепления методов. Для определения этого параметра рассмотрим класс C с n методами M1, M2,… ,Mn, тогда {I1},{I2},…,{In} — множества переменных, используемых в данных методах. Теперь определим P — множество пар методов, не имеющих общих переменных; Q — множество пар методов, имеющих общие переменные. Тогда LCOM=|P|-|Q|. Недостаток сцепления может быть сигналом того, что класс можно разбить на несколько других классов или подклассов, так что для повышения инкапсуляции данных и уменьшения сложности классов и методов лучше повышать сцепление.

6. Метрики надежности

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

7. Гибридные метрики

В завершении необходимо упомянуть еще один класс метрик, называемых гибридными. Метрики данного класса основываются на более простых метриках и представляют собой их взвешенную сумму. Первым представителем данного класса является метрика Кокола. Она определяется следующим образом:

H_M = (M + R1 * M(M1) +… + Rn * M(Mn)/(1 + R1 +… + Rn)

Где M — базовая метрика, Mi — другие интересные меры, Ri — корректно подобранные коэффициенты, M(Mi) — функции.

Функции M(Mi) и коэффициенты Ri вычисляются с помощью регрессионного анализа или анализа задачи для конкретной программы.

В результате исследований, автор метрики выделил три модели для мер: Маккейба, Холстеда и SLOC, где в качестве базовой используется мера Холстеда. Эти модели получили название «наилучшая», «случайная» и «линейная».

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

(структура, взаимодействие, объем, данные) СУММА(a, b, c, d).

(сложность интерфейса, вычислительная сложность, сложность ввода/вывода, читабельность) СУММА(x, y, z, p).

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

Заключение

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

Bugs Per Line Of Code

Bugs / LOC is only relative to an individual. For businesses that implement bug tracking tools that link with their source code repository. It’s possible for a manager to organize issues by developer, sorted by past issues and code changes.

Bugs Are Relative To Your Job

A senior software developer, who is highly experienced, highly skilled, very smart and able to take on independent jobs is far more likely to have way more bugs logged in a tracking system, then a junior developer with little experience.

How is that possible?

Senior developers are often engaged in higher risk development tasks. Refactoring of code and building new systems as an example. Junior developers are often assigned to fix known issues that aren’t worth the time of a senior developer.

Therefore, by task assignment a junior isn’t introducing bugs but fixing them, and a senior developer is allowed the risk of introducing them, because the benefit of what they are trying to archive is more important then the minor issues that are raised completing those tasks.

Language Syntax Is Important

The argument that a language introduces less bugs, because it can achieve more in fewer lines of code is a complete myth. Highly structured languages like C++/C#/Java force the developer to clearly express in writing what the desired instruction should be, where as languages like Python/PHP are very unstructured. Those languages allow for written expressions that not only will confuse a developer, but also the language parser.

The Compiler Reduces Bugs

How many bugs in Python/PHP have made it out into production servers, because there was no compiler to warn the developer that something was incorrect. When you measure bugs per LOC is that before or after a compiler has processed the source code?

Update 2019:

Compilers make no difference on the nature or number of bugs. Bugs are purely relative to the person who wrote the source code, and bugs themselves can be very subjective in nature.

Качество программного обеспечения.

Проблемы разработки ПО

Наиболее распространёнными проблемами, возникающим в процессе разработки ПО, считают:

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

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

·         Недостаток контроля. Без точной оценки процесса разработки срываются графики выполнения работ и превышаются установленные бюджеты. Сложно оценить объем выполненной и оставшейся работы.

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

·         Недостаток трассировки.

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

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

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

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

·         Недостаточная надежность. Самый сложный процесс — поиск и исправление ошибок в программах на ЭВМ. Поскольку число ошибок в программах заранее неизвестно, то заранее неизвестна и продолжительность отладки программ и отсутствие гарантий отсутствия ошибок в программах. Следует отметить, что привлечение доказательного подхода к проектированию ПО позволяет обнаружить ошибки в программе до её выполнения. В этом направлении много работали Кнут, Дейкстра и Вирт. Профессор Вирт при разработке Паскаля и Оберона за счет строгости их синтаксиса добился математической доказуемости завершаемости и правильности программ, написанной на этих языках. Особенно крупный вклад в дисциплину программирования внёс Дональд Кнут. Его четырёхтомник «Искусство программирования» является необходимой для каждого серьезного программиста книгой.

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

·         Отсутствие гарантий качества и надежности программ из-за отсутствия гарантий отсутствия ошибок в программах вплоть до формальной сдачи программ заказчикам.

Данная проблема не является проблемой, относящейся исключительно к разработке ПО. Гарантия качества — это проблема выбора поставщика товара (не продукта).

Качество программного обеспечения — характеристика программного обеспечения (ПО) как степени его соответствия требованиям. При этом требования могут трактоваться довольно широко, что порождает целый ряд независимых определений понятия. Чаще всего используется определение ISO 9001, согласно которому качество есть «степень соответствия присущих характеристик требованиям».

Качество исходного кода

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

·         Структурированность — степень логического разбиения кода на ряд управляемых блоков

·         Читаемость кода

·         Лёгкость поддержки, тестирования, отладки, исправления ошибок, изменения и портируемости

·         Низкая сложность кода

·         Низкое использование ресурсов: памяти и процессорного времени

·         Корректная обработка исключительных ситуаций

·         Низкое количество предупреждений при компиляции и линковке

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

Методы улучшения качества кода: рефакторинг.

Факторы качества

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

Некоторые из факторов качества:

·         понятность

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

·         полнота

Все необходимые части программы должны быть представлены и полностью реализованы.

·         краткость

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

·         портируемость

Лёгкость в адаптации программы к другому окружению: другой архитектуре, платформе, операционной системе или её версии.

·         согласованность

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

·         сопровождаемость

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

·         тестируемость

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

·         удобство использования

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

·         надёжность

отсутствие отказов и сбоев в работе программ, а также простота исправления дефектов и ошибок:

·         структурированность

·         эффективность

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

·         безопасность

С точки зрения пользователя

Помимо технического взгляда на качество ПО, существует и оценка качества с позиции пользователя. Для этого аспекта качества иногда используют термин «юзабилити» (англ. usability — дословно «возможность использования», «способность быть использованным», «полезность»). Довольно сложно получить оценку юзабилити для заданного программного продукта. Наиболее важные из вопросов, влияющих на оценку:

·         Является ли пользовательский интерфейс интуитивно понятным?

·         Насколько просто выполнять простые, частые операции?

·         Насколько легко выполняются сложные операции?

·         Выдаёт ли программа понятные сообщения об ошибках?

·         Всегда ли программа ведёт себя так, как ожидается?

·         Имеется ли документация и насколько она полна?

·         Является ли интерфейс пользователя само-описательным/само-документирующим?

·         Всегда ли задержки с ответом программы являются приемлемыми?

Методы улучшения качества кода: рефакторинг.

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

Цели рефакторинга

Цель рефакторинга — сделать код программы более легким для понимания; без этого рефакторинг нельзя считать успешным. Рефакторинг следует отличать от оптимизации производительности. Как и рефакторинг, оптимизация обычно не изменяет поведение программы, а только ускоряет ее работу. Но оптимизация часто затрудняет понимание кода, что противоположно рефакторингу. С другой стороны, нужно отличать рефакторинг от реинжиниринга, который осуществляется для расширения функциональности программного обеспечения. Как правило, крупные рефакторинги предваряют реинжиниринг.

Причины применения рефакторинга

Рефакторинг нужно применять постоянно при разработке кода. Основными стимулами его проведения являются следующие задачи:

·         Необходимо добавить новую функцию, которая не достаточно укладывается в принятое архитектурное решение

·         Необходимо исправить ошибку, причины возникновения которой сразу не ясны

·         Трудности в командной разработке обусловлены сложной логикой программы

Какой код должен подвергаться рефакторингу

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

·         Дублирование кода

·         Длинный метод

·         Большой класс

·         Длинный список параметров

·         «Завистливые» функции — это метод, который чрезмерно обращается к данным другого объекта

·         Избыточные временные переменные

·         Классы данных

·         Несгруппированные данные

Рефакторинг кода

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

Рефакторинг изначально не предназначен для исправления ошибок и добавления новой функциональности, он вообще не меняет поведение программного обеспечения. Но это помогает избежать ошибок и облегчить добавление функциональности. Он выполняется для улучшения понятности кода или изменения его структуры, для удаления «мёртвого кода» — всё это для того, чтобы в будущем код было легче поддерживать и развивать. В частности, добавление в программу нового поведения может оказаться сложным с существующей структурой — в этом случае разработчик может выполнить необходимый рефакторинг, а уже затем добавить новую функциональность.

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

Методы рефакторинга

Наиболее употребимые методы рефакторинга:

·         Изменение сигнатуры метода (Change Method Signature)

·         Инкапсуляция поля (Encapsulate Field)

·         Выделение класса (Extract Class)

·         Выделение интерфейса (Extract Interface)

·         Выделение локальной переменной (Extract Local Variable)

·         Выделение метода (Extract Method)

·         Генерализация типа (Generalize Type)

·         Встраивание (Inline)

·         Введение фабрики (Introduce Factory)

·         Введение параметра (Introduce Parameter)

·         Подъём поля/метода (Pull Up)

·         Спуск поля/метода (Push Down)

·         Замена условного оператора полиморфизмом (Replace Conditional with Polymorphism)

Изменение сигнатуры метода (Change Method Signature)

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

Инкапсуляция поля (Encapsulate field)

В случае, если у класса имеется открытое поле, необходимо сделать его закрытым и обеспечить методы доступа. После «Инкапсуляции поля» часто применяется «Перемещение метода».

Выделение метода (Extract Method)

Заключается в выделении из длинного и/или требующего комментариев кода отдельных фрагментов и преобразовании их в отдельные методы, с подстановкой подходящих вызовов в местах использования. В этом случае действует правило: если фрагмент кода требует комментария о том, что он делает, то он должен быть выделен в отдельный метод. Также правило: один метод не должен занимать более чем один экран (25-50 строк, в зависимости от условий редактирования), в противном случае некоторые его фрагменты имеют самостоятельную ценность и подлежат выделению. Из анализа связей выделяемого фрагмента с окружающим контекстом делается вывод о перечне параметров нового метода и его локальных переменных.

Перемещение метода (Move Method)

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

Замена условного оператора полиморфизмом (Replace Conditional with Polymorphism)

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

Основные принципы:

1.       вначале следует создать базовый класс и нужное число подклассов

2.       в некоторых случаях следует провести оптимизацию условного оператора путем «Выделения метода»

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

4.       выбрав один из подклассов, нужно конкретизировать в нём полиморфный метод базового класса и переместить в него тело соответствующей ветви условного оператора.

5.       повторить предыдущее действие для каждой ветви условного оператора

6.       заменить весь условный оператор вызовом полиморфного метода базового класса

Проблемы, возникающие при проведении рефакторинга

·         проблемы, связанные с базами данных

·         проблемы изменения интерфейсов

·         трудности при изменении дизайна

Реинжиниринг программного обеспечения.

Реинжиниринг программного обеспечения — процесс создания новой функциональности или устранения ошибок, путём революционного изменения, но используя уже имеющееся в эксплуатации программное обеспечение. Процесс реинжиниринга описан Chikofsky и Кроссом в их труде 1990 года, как «The examination and alteration of a system to reconstitute it in a new form». Выражаясь менее формально, реинжиниринг является изменением системы программного обеспечения после проведения обратного инжиниринга.

Сложность реинжиниринга

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

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

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

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

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

Тестирование программного обеспечения.

Тестирование программного обеспечения — процесс исследования программного обеспечения (ПО) с целью получения информации о качестве продукта.

Введение

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

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

Существует множество подходов к решению задачи тестирования и верификации ПО, но эффективное тестирование сложных программных продуктов — это процесс в высшей степени творческий, не сводящийся к следованию строгим и чётким процедурам или созданию таковых.

С точки зрения ISO 9126, Качество (программных средств) можно определить как совокупную характеристику исследуемого ПО с учётом следующих составляющих:

·         Надёжность

·         Сопровождаемость

·         Практичность

·         Эффективность

·         Мобильность

·         Функциональность

Более полный список атрибутов и критериев можно найти в стандарте ISO 9126 Международной организации по стандартизации. Состав и содержание документации, сопутствующей процессу тестирования, определяется стандартом IEEE 829-1998 Standard for Software Test Documentation.

История развития тестирования программного обеспечения

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

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

В начале 1970-х тестирование ПО обозначалось как «процесс, направленный на демонстрацию корректности продукта» или как «деятельность по подтверждению правильности работы ПО». В зарождавшейся программной инженерии верификация ПО значилась как «доказательство правильности». Хотя концепция была теоретически перспективной, на практике она требовала много времени и была недостаточно всеобъемлющей. Было решено, что доказательство правильности — неэффективный метод тестирования ПО. Однако, в некоторых случаях демонстрация правильной работы используется и в наши дни, например, приемо-сдаточные испытания. Во второй половине 1970-х тестирование представлялось как выполнение программы с намерением найти ошибки, а не доказать, что она работает. Успешный тест — это тест, который обнаруживает ранее неизвестные проблемы. Данный подход прямо противоположен предыдущему. Указанные два определения представляют собой «парадокс тестирования», в основе которого лежат два противоположных утверждения: с одной стороны, тестирование позволяет убедиться, что продукт работает хорошо, а с другой — выявляет ошибки в ПО, показывая, что продукт не работает. Вторая цель тестирования является более продуктивной с точки зрения улучшения качества, так как не позволяет игнорировать недостатки ПО.

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

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

В 2000-х появилось еще более широкое определение тестирования, когда в него было добавлено понятие «оптимизация бизнес-технологий» (en:business technology optimization, BTO). BTO направляет развитие информационных технологий в соответствии с целями бизнеса. Основной подход заключается в оценке и максимизации значимости всех этапов жизненного цикла разработки ПО для достижения необходимого уровня качества, производительности, доступности.

Тестирование программного обеспечения

Существует несколько признаков, по которым принято производить классификацию видов тестирования. Обычно выделяют следующие:

По объекту тестирования:

·         Функциональное тестирование (functional testing)

·         Нагрузочное тестирование

·         Тестирование производительности (perfomance/stress testing)

·         Тестирование стабильности (stability/load testing)

·         Тестирование удобства использования (usability testing)

·         Тестирование интерфейса пользователя (UI testing)

·         Тестирование безопасности (security testing)

·         Тестирование локализации (localization testing)

·         Тестирование совместимости (compatibility testing)

По знанию системы:

·         Тестирование чёрного ящика (black box)

·         Тестирование белого ящика (white box)

·         Тестирование серого ящика (gray box)

По степени автоматизированности:

·         Ручное тестирование (manual testing)

·         Автоматизированное тестирование (automated testing)

·         Полуавтоматизированное тестирование (semiautomated testing)

По степени изолированности компонентов:

·         Компонентное (модульное) тестирование (component/unit testing)

·         Интеграционное тестирование (integration testing)

·         Системное тестирование (system/end-to-end testing)

По времени проведения тестирования:

·         Альфа тестирование (alpha testing)

·         Тестирование при приёмке (smoke testing)

·         Тестирование новых функциональностей (new feature testing)

·         Регрессионное тестирование (regression testing)

·         Тестирование при сдаче (acceptance testing)

·         Бета тестирование (beta testing)

По признаку позитивности сценариев:

·         Позитивное тестирование (positive testing)

·         Негативное тестирование (negative testing)

По степени подготовленности к тестированию:

·         Тестирование по документации (formal testing)

·         Эд Хок (интуитивное) тестирование (ad hoc testing)

Уровни тестирования

Модульное тестирование (юнит-тестирование) — тестируется минимально возможный для тестирования компонент, например, отдельный класс или функция. Часто модульное тестирование осуществляется разработчиками ПО.

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

Системное тестирование — тестируется интегрированная система на её соответствие требованиям.

Альфа-тестирование — имитация реальной работы с системой штатными разработчиками, либо реальная работа с системой потенциальными пользователями/заказчиком. Чаще всего альфа-тестирование проводится на ранней стадии разработки продукта, но в некоторых случаях может применяться для законченного продукта в качестве внутреннего приёмочного тестирования. Иногда альфа-тестирование выполняется под отладчиком или с использованием окружения, которое помогает быстро выявлять найденные ошибки. Обнаруженные ошибки могут быть переданы тестировщикам для дополнительного исследования в окружении, подобном тому, в котором будет использоваться ПО.

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

Часто для свободного/открытого ПО стадия Альфа-тестирования характеризует функциональное наполнение кода, а Бета тестирования — стадию исправления ошибок. При этом как правило на каждом этапе разработки промежуточные результаты работы доступны конечным пользователям.

Тестирование «белого ящика» и «чёрного ящика»

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

При тестировании белого ящика (англ. white-box testing, также говорят — прозрачного ящика), разработчик теста имеет доступ к исходному коду программ и может писать код, который связан с библиотеками тестируемого ПО. Это типично для юнит-тестирования (англ. unit testing), при котором тестируются только отдельные части системы. Оно обеспечивает то, что компоненты конструкции — работоспособны и устойчивы, до определённой степени. При тестировании белого ящика используются метрики покрытия кода.

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

Если «альфа-» и «бета-тестирование» относятся к стадиям до выпуска продукта (а также, неявно, к объёму тестирующего сообщества и ограничениям на методы тестирования), тестирование «белого ящика» и «чёрного ящика» имеет отношение к способам, которыми тестировщик достигает цели.

Бета-тестирование в целом ограничено техникой чёрного ящика (хотя постоянная часть тестировщиков обычно продолжает тестирование белого ящика параллельно бета-тестированию). Таким образом, термин «бета-тестирование» может указывать на состояние программы (ближе к выпуску чем «альфа»), или может указывать на некоторую группу тестировщиков и процесс, выполняемый этой группой. Итак, тестировщик может продолжать работу по тестированию белого ящика, хотя ПО уже «в бете» (стадия), но в этом случае он не является частью «бета-тестирования» (группы/процесса).

Статическое и динамическое тестирование

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

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

Также к статическому тестированию относят тестирование требований, спецификаций, документации.

Регрессионное тестирование

Регрессио́нное тести́рование (англ. regression testing, от лат. regressio — движение назад) — собирательное название для всех видов тестирования программного обеспечения, направленных на обнаружение ошибок в уже протестированных участках исходного кода. Такие ошибки — когда после внесения изменений в программу перестает работать то, что должно было продолжать работать, — называют регрессионными ошибками (англ. regression bugs).

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

Из опыта разработки ПО известно, что повторное появление одних и тех же ошибок — случай достаточно частый. Иногда это происходит из-за слабой техники управления версиями или по причине человеческой ошибки при работе с системой управления версиями. Но настолько же часто решение проблемы бывает «недолго живущим»: после следующего изменения в программе решение перестаёт работать. И наконец, при переписывании какой-либо части кода часто всплывают те же ошибки, что были в предыдущей реализации.

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

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

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

Цитата

«Фундаментальная проблема при сопровождении программ состоит в том, что исправление одной ошибки с большой вероятностью (20-50%) влечет появление новой. Поэтому весь процесс идет по принципу «два шага вперед, шаг назад».

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

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

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

Тестовые скрипты

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

Покрытие кода

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

Критерии

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

·         Покрытие операторов — каждая ли строка исходного кода была выполнена и протестирована?

·         Покрытие условий — каждая ли точка решения (вычисления истинно ли или ложно выражение) была выполнена и протестирована?

·         Покрытие путей — все ли возможные пути через заданную часть кода были выполнены и протестированы?

·         Покрытие функций — каждая ли функция программы была выполнена

·         Покрытие вход/выход — все ли вызовы функций и возвраты из них были выполнены

Для программ с особыми требованиями к безопасности часто требуется продемонстрировать, что тестами достигается 100 % покрытие для одного из критериев. Некоторые из приведённых критериев покрытия связаны между собой; например, покрытие путей включает в себя и покрытие условий и покрытие операторов. Покрытие операторов не включает покрытие условий, как показывает этот код на Си:

printf(«this is «);

if (bar < 1)

{

    printf(«not «);

}

printf(«a positive integer»);

Если здесь bar = −1, то покрытие операторов будет полным, а покрытие условий — нет, так как случай несоблюдения условия в операторе if — не покрыт. Полное покрытие путей обычно невозможно. Фрагмент кода, имеющий n условий содержит 2n путей; конструкция цикла порождает бесконечное количество путей. Некоторые пути в программе могут быть не достигнуты из-за того, что в тестовых данных отсутствовали такие, которые могли привести к выполнению этих путей. Не существует универсального алгоритма, который решал бы проблему недостижимых путей (этот алгоритм можно было бы использовать для решения проблемы останова). На практике для достижения покрытия путей используется следующий подход: выделяются классы путей (например, к одному классу можно отнести пути отличающиеся только количеством итераций в одном и том же цикле), 100 % покрытие достигнуто, если покрыты все классы путей (класс считается покрытым, если покрыт хотя бы один путь из него).

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

Практическое применение

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

Степень покрытия кода обычно выражают в виде процента. Например, «мы протестировали 67 % кода». Смысл этой фразы зависит от того какой критерий был использован. Например, 67 % покрытия путей — это лучший результат чем 67 % покрытия операторов. Вопрос о связи значения покрытия кода и качеством тестового набора ещё до конца не решён.

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

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

Метрика программного обеспечения

Метрика программного обеспечения (англ. software metric) — это мера, позволяющая получить численное значение некоторого свойства программного обеспечения или его спецификаций.

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

Метрики

Набор используемых метрик включает:

·         порядок роста (имеется в виду анализ алгоритмов в терминах асимптотического анализа и O-нотации)

·         количество строк кода

·         цикломатическая сложность

·         анализ функциональных точек

·         количество ошибок на 1000 строк кода

·         покрытие кода

·         покрытие требований

·         количество классов и интерфейсов

·         метрики программного пакета от Роберта Сесиль Мартина

·         связность

Критика

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

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

Замещение «управления людьми» на «управление цифрами», которое не учитывает опыт сотрудников и их другие качества

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

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

Обратная семантическая трассировка

Обратная семантическая трассировка (ОСТ) — метод контроля качества, который позволяет обнаруживать ошибки, утечку или искажение информации при создании проектных артефактов: документации, кода и т. д. Метод наиболее ценен на ранних стадиях разработки программного обеспечения, при создании требований и архитектуры будущей системы при отсутствии исполняемого кода для тестирования. ОСТ является частью P-Modeling Framework.

Вступление

Каждый этап процесса разработки программного обеспечения можно рассматривать как серию «переводов» с одного языка на другой. В самом начале проекта заказчик рассказывает команде свои требования к программе на естественном языке: русском, английском и т. д. Эти пожелания клиента иногда могут оказаться неполными, неясными или даже противоречащими друг другу. Первым шагом в цепочке «переводов» является определение и анализ пожеланий заказчика, их преобразование в формальный список требований для будущей системы. Затем требования становятся исходным материалом для архитектуры и проекта системы. Так шаг за шагом команда создает мегабайты кода, написанного на весьма формальном языке программирования. При переводе всегда существует риск ошибки, неправильного толкования или потери информации. Иногда это не имеет значения, но иногда даже небольшой дефект в спецификации требований может вызвать серьезные переделки системы на поздних стадиях проекта.

Чаще всего обратная семантическая трассировка применяется для:

·         Проверки UML моделей;

·         Проверки изменений в требованиях;

·         Проверки исправлений ошибок в коде;

·         Быстрой адаптации нового человека в команде (новому члену команды дают задание провести ОСТ сессию — он знакомится с программой, документацией, кодом и т. д. гораздо быстрее, так как ему необходимо не просто прочитать материал, но и проанализировать его).

·

Роли

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

·         авторы артефактов (как исходного, так и результирующего);

·         реверс-инженеры;

·         группа экспертов для оценки качества артефакта;

·         менеджер проекта.

Процесс

Определить все артефакты проекта и их взаимосвязи

Обратная семантическая трассировка, как метод контроля качества, может быть применена к любому артефакту проекта, даже к любой части артефакта, вплоть до одной строки документа или кода. Однако очевидно, что выполнение такой процедуры для всех документов и изменений может создать ненужную нагрузку для проектной команды. Чтобы этого избежать, применение ОСТ должно быть обосновано. Какой объем ОСТ нужен для обеспечения качества — решает компания (в соответствие со стандартами качества и процессами, принятым в компании) и проджект менеджер (исходя из специфики конкретного проекта).

В общем случае, количество ОСТ сессий определяется важностью артефактов для проекта и уровнем контроля качества для этого артефакта (тестирование, верификация, рецензии и т. д.)

Количество ОСТ сессий определяется на этапе планирования проекта.

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

Расставить приоритеты для артефактов

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

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

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

Средняя(3): артефакт имеет среднее или косвенное влияние на качество конечного продукта. Например: план проекта, дефекты со средним приоритетом.

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

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

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

Средний(2): Рецензия не предусмотрена, над артефактом работает нераспределенная команда.

Достаточный(3): Предусмотрено рецензирование или парное программирование, над артефактом работает нераспределенная команда.

Отличный(4): Для артефакта предусмотрены парное программирование, верификация и\или тестирование, автоматическое или юнит тестирование. Есть инструменты для создания или тестирования артефактов.

Определить, кто будет проводить ОСТ

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

Провести ОСТ

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

Менеджер проекта определяет какие документы будут являться входными для данной сессии ОСТ. Например, это может быть дополнительная информация, которая позволит реверс-инжерену восстановить родительский артефакт более полно. Рекомендуется также дать информацию о размере восстанавливаемого артефакта, чтобы помочь реверс-инженерам определить объем работы: это может быть одна-две строки или несколько страниц текста. И хотя восстановленный текст может не совпадать с исходным по количеству слов, эти величины должны быть соизмеримы.

После этого реверс-инженеры берут артефакт и восстанавливают из него исходный текст. ОСТ сессия сама по себе занимает около часа (для 1 страницы текста, примерно 750 слов)

Оценить качество артефактов

Чтобы завершить ОСТ сессию, необходимо сравнить исходный и восстановленный текст и оценить качество артефактов. Решение о переработке, доработке и исправлении артефактов делается на основании этой оценки.

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

Критерии оценки и шкала:

1.       Восстановленный и оригинальный тексты имеют очень большие смысловые различия и потери критической информации.

2.       Восстановленный и оригинальный тексты имеют смысловые различия, потерю или искажение важной информации.

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

4.       Восстановленный и оригинальный тексты близки по смыслу, незначительное искажение информации.

5.       Восстановленный и оригинальный тексты очень близки, информация не потеряна (искажена).

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

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

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

Если средняя оценка от 3 до 4, требуется доработка тестируемого артефакта, чтобы исправить неточности.

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

Естественно, финальное решение принимает менеджер проекта, и оно должно учитывать причины расхождений в исходном и восстановленном текстах.

Урок 32.

Предмет: Технология
разработки программных продуктов.

Тема: Метрики
измерения программного продукта.

Цели:

Образовательная

Ознакомление с метриками измерения ПО.

Развивающая:

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

Воспитательная:

Воспитывать чувство значимости предмета в профессиональной
деятельности, аккуратности в работе

Межпредметные связи:

        
Английский язык

        
Операционные системы

        
Информационные технологии

        
Основы алгоритмизации и программирования

Оборудование: доска, мел, письменные принадлежности,
проектор, ПК

Тип урока: комбинированный

Метод обучения: Объяснительно иллюстративный

Ход урока:

1.Организационный момент

         — Проверка
готовности кабинета

         — Объявление
темы

2. Постановка цели урока

3.Повторение пройденного материала

Эффективность и оптимизация
программ

Способы экономии памяти.

Способы уменьшения времени
выполнения.

Сопровождение программного продукта

Отладка программного продукта

4.Сообщение новых знаний

  1. Основные
    понятия
  2. Измерения,
    меры и метрики.
  3. Размерно-ориентированные
    метрики
  4. Функционально-ориентированные
    метрики
  5. Выполнение
    оценки проекта на основе LOC- и FP-метрик
  6. Метрики
    объектно-ориентированных программных систем
  7. Набор
    метрик Чидамбера и Кемерера
  8. Метрики
    Лоренца и Кидда

5. Восприятие и осознание учащимися нового материала

6. Осмысление обобщение и систематизация знаний

7. Подведение итогов урока и 
постановка домашнего задания

   Выучить содержимое
темы

Орлов С.А. стр.189-209

        Ответить на
вопросы:

1.Основные
понятия

Ме́трика програ́ммного
обеспе́чения
(англ. software metric) — это мера,
позволяющая получить численное значение некоторого свойства программного обеспечения или его спецификаций.

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

Набор используемых метрик включает:

  • порядок роста (имеется в виду анализ алгоритмов в терминах асимптотического анализа и O-нотации),
  • количество строк кода,
  • цикломатическая сложность,
  • анализ
    функциональных точек
    ,
  • количество ошибок
    на 1000 строк кода,
  • степень покрытия кода тестированием,
  • покрытие требований,
  • количество классов и интерфейсов,
  • метрики
    программного пакета
    от Роберта Сесиль Мартина,
  • связность.

Цикломати́ческая
сло́жность програ́ммы

(англ. 
Cyclomatic complexity of a program) — структурная (или топологическая) мера сложности программ, используемая для
измерения качества программного обеспечения, основанная на методах
статического анализа кода.

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

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

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

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

Связность или сцепление (англ. cohesion) —
характеристика внутренней взаимосвязи между частями одного модуля (сравни со связанностью).

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

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

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

Примеры

Размеры исходных кодов операционных систем семейства Microsoft
Windows NT
точно не известны, но согласно источнику [4]
они составляют:

Год

Версия

Cтрок кода

1994

Windows NT 3.5

4 000 000

1996

Windows NT 4

16 500 000

2000

Windows 2000

20 000 000

2002

Windows XP

40 000 000

Размеры исходных кодов ядра Linux вместе с включёнными туда драйверами устройств
можно посчитать точно:

Год

Версия

Cтрок кода

1991

Ядро Linux 0.1

10 239

1994

Ядро Linux 1.0.0

176 250

1995

Ядро Linux 1.2.0

310 950

1996

Ядро Linux 2.0.0

777 956

1999

Ядро Linux 2.2.0

1 800 847

2001

Ядро Linux 2.4.0

3 377 902

2003

Ядро Linux 2.6.0

5 929 913

2009

Ядро Linux 2.6.32

12 606 910[5]

Размеры других систем:

Год

Версия

Cтрок кода

PostgreSQL

775 000

1C

3 000 000

2008

1С-Битрикс

762 854

2. Измерения, меры и метрики. Размерно-ориентированные
метрики. Функционально-ориентированные метрики.

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

Измерения
при разработке ПО необходимы для того, чтобы:


определить или показать качество продукции;


оценить производительность труда персонала, занятого разработкой;


оценить выгоды (прибыль или доход), которые могут быть получены в результате
разработки новых программных средств;


сформировать основу (базовую линию) для последующих оценок;


получить данные для обоснования запросов на дополнительные средства, обучение и
т.п.

Измерения
бывают прямые и косвенные. Результаты прямых измерений процесса разработки и
сопровождения программного изделия: трудозатраты и стоимость, число строк кода
(LOC — lines-of-code), размер требуемой памяти, скорость выполнения программы,
число ошибок (дефектов), обнаруженных за определенный период времени. Косвенные
измерения дают оценку функциональных возможностей, показателей качества
программного продукта (надежность, эффективность, пригодность к сопровождению и
т.п.).

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

Вторая
классификация метрик — классификация по признаку их ориентации:


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


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


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

3.Размерно-ориентированные метрики

Размерно-ориентированные
метрики прямо измеряют программный продукт и процесс его разработки.
Основываются такие метрики на LOC-оценках (Lines Of Code). LOC-оценка — это
количество строк в программном продукте. Принято регистрировать следующие
показатели:


общие затраты (в человеко-месяцах — чел.-мес);


объем программного изделия (в тысячах строк исходного кода -KLOC);


стоимость разработки (в тыс.рублей или в долларах $);


объем документации (в страницах документов -СД);


ошибки, обнаруженные в течение первого года эксплуатации (число ошибок — ЧО);


число людей, работавших над изделием (человек);


срок разработки (в календарных месяцах).

На
основе перечисленных показателей вычисляются размерно-ориентированные метрики
производительности и качества (для каждого проекта):

Достоинства
размерно-ориентированных метрик:

1)
широко распространены;

2)
просты и легко вычисляются.

Недостатки
размерно-ориентированных метрик:

1)
зависимы от языка программирования;

2)
требуют исходных данных, которые трудно получить на начальной стадии проекта;

3)
не приспособлены к непроцедурным языкам программирования.

4.Функционально-ориентированные метрики

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

1.
Количество внешних вводов. Подсчитываются все вводы пользователя, по которым
поступают разные прикладные данные. Вводы должны быть отделены от запросов,
которые подсчитываются отдельно.

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

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

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

5.
Количество внешних интерфейсных файлов. Подсчитываются все логические файлы из
других приложений, на которые ссылается данное приложение.

Количество
функциональных указателей вычисляется по формуле

После
вычисления FP на его основе формируются метрики производительности, качества и
т. д.:

Область
применения метода функциональных указателей — коммерческие информационные
системы. Для продуктов с высокой алгоритмической сложностью используются
метрики указателей свойств (Features Points). Они применимы к системному и
инженерному ПО. ПО реального времени и встроенному ПО. Для вычисления указателя
свойств добавляется одна характеристика — количество алгоритмов. Алгоритм здесь
определяется как ограниченная подпрограмма вычислений, которая включается в
общую компьютерную программу. Примеры алгоритмов: обработка прерываний,
инвертирование матрицы, расшифровка битовой строки. Для формирования указателя
свойств составляется табл. 6.

Достоинства
функционально-ориентированных метрик:

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

2.
Легко вычисляются на любой стадии проекта.

Недостаток
функционально-ориентированных метрик: результаты основаны на субъективных
данных, используются не прямые, а косвенные измерения.

FP-оценки
легко пересчитать в LOC-оценки. Результаты пересчета зависят от языка
программирования, используемого для реализации ПО.

5..
Выполнение оценки проекта на основе LOC- и FP-метрик

Цель
этой деятельности — сформировать предварительные оценки, которые позволят:


предъявить заказчику корректные требования по стоимости и затратам на
разработку программного продукта;


составить план программного проекта.

При
выполнении оценки возможны два варианта использования LOC- и FP-данных:


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


в качестве метрик, собранных за прошлые проекты и входящих в метрический базис
фирмы.

Порядок
проведения процедуры оценки.

1.
Область назначения проектируемого продукта разбивается на ряд функций, каждую
из которых можно оценить индивидуально: f1 , f2 ,…, fn.

2.
Для каждой функции fi планировщик формирует лучшую LOCлучшi(FPлучшi), худшую
LOCхудшi(FPхудшi) и вероятную оценку LOCвер i(FPвер i). Используются опытные
данные (из метрического базиса) или интуиция. Диапазон значения оценок
соответствует степени предусмотренной неопределенности.

3.
Для каждой функции fi в соответствии с -распределением вычисляется ожидаемое
значение LOC- (или FP-) оценки:

4.
Определяется значение LOC- или FP-производительности разработки функции.
Используется один из трех подходов:

а)
для всех функции принимается одна и та же метрика средней производительности
ПРОИЗВср, взятая из метрического базиса;

б)
для i-й функции на основе метрики средней производительности вычисляется
настраиваемая величина производительности:

,где
LOCcp — средняя LOC-оценка, взятая из метрического базиса (соответствует
средней производительности);

в)
для i-й функции настраиваемая величина производительности вычисляется по
аналогу, взятому из метрического базиса: ,

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

5.
Вычисляется общая оценка затрат на проект

6.Метрики объектно-ориентированных
программных систем

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

 

Метрические
особенности объектно-ориентированных программных систем

Объектно-ориентированные метрики вводятся с
целью:

q      
улучшить понимание
качества продукта;

q      
оценить эффективность
процесса конструирования;

q      
улучшить качество
работы на этапе проектирования.

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

Для любого инженерного продукта метрики должны
ориентироваться на его уникальные характеристики. Например, для электропоезда
вряд ли полезна метрика «расход угля на километр пробега». С точки зрения
метрик выделяют пять характеристик объектно-ориентированных систем:
локализацию, инкапсуляцию, информационную закрытость, наследование и способы
абстрагирования объектов. Эти характеристики оказывают максимальное влияние на
объектно-ориентированные метрики.

Локализация

Локализация фиксирует способ группировки информации
в программе. В классических методах, где используется функциональная
декомпозиция, информация локализуется вокруг функций. Функции в них реализуются
как процедурные модули. В методах, управляемых данными, информация группируется
вокруг структур данных. В объектно-ориентированной среде информация
группируется внутри классов или объектов (инкапсуляцией как данных, так и
процессов).

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

Так как в объектно-ориентированной системе
базовым элементом является класс, то локализация здесь основывается на
объектах. Поэтому метрики должны применяться к классу (объекту) как к
комплексной сущности. Кроме того, между операциями (функциями) и классами могут
быть отношения не только «один-к-одному». Поэтому метрики, отображающие способы
взаимодействия классов, должны быть приспособлены к отношениям
«один-ко-многим», «многие-ко-многим».

Инкапсуляция

Вспомним, что инкапсуляция — упаковка
(связывание) совокупности элементов. Для классических ПС примерами
низкоуровневой инкапсуляции являются записи и массивы. Механизмом инкапсуляции
среднего уровня являются подпрограммы (процедуры, функции).

В объектно-ориентированных системах
инкапсулируются обязанности класса, представляемые его свойствами (а для
агрегатов — и свойствами других классов), операциями и состояниями.

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

Информационная
закрытость

Информационная закрытость делает невидимыми операционные
детали программного компонента. Другим компонентам доступна только необходимая
информация.

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

Наследование

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

Поскольку наследование — основная
характеристика объектно-ориентированных систем, на ней фокусируются многие
объектно-ориентированные метрики (количество детей — потомков класса,
количество родителей, высота класса в иерархии наследования).

Абстракция

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

Класс — это абстракция, которая может быть
представлена на различных уровнях детализации и различными способами (например,
как список операций, последовательность состояний, последовательности
взаимодействий). Поэтому объектно-ориентированные метрики должны представлять
абстракции в терминах измерений класса. Примеры: количество экземпляров класса
в приложении, количество родовых классов на приложение, отношение количества
родовых к количеству неродовых классов.

Эволюция
мер связи для объектно-ориентированных программных систем

В разделах «Связность модуля» и «Сцепление
модулей» главы 4 было показано, что классической мерой сложности внутренних
связей модуля является связность, а
классической мерой сложности внешних связей — сцепление. Рассмотрим развитие
этих мер применительно к объектно-ориентированным системам.

7.Набор метрик Чидамбера и Кемерера

В 1994 году С. Чидамбер и К. Кемерер (Chidamber и Кетегег) предложили шесть проектных метрик,
ориентированных на классы [24]. Класс — фундаментальный элемент
объектно-ориентированной (ОО) системы. Поэтому измерения и метрики для
отдельного класса, иерархии классов и сотрудничества классов бесценны для
программного инженера, который должен оценить качество проекта.

Набор Чидамбера-Кемерера наиболее часто
цитируется в программной индустрии и научных исследованиях. Рассмотрим каждую
из метрик набора.

Метрика 1: Взвешенные методы на класс WMC (Weighted Methods Per Class)

Допустим, что в классе С определены п методов со
сложностью с1,
c2,…, сn. Для оценки сложности
может быть выбрана любая метрика сложности (например, цикломатическая
сложность). Главное — нормализовать эту метрику так, чтобы номинальная
сложность для метода принимала значение 1. В этом случае

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

Очень часто применяют упрощенную версию
метрики. При этом полагают С
i= 1, и тогда
WMC — количество методов в классе.

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

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

2.             
Подсчитываются методы,
определенные в текущем классе, и все унаследованные методы. Этот подход
подчеркивает важность пространства состояний в понимании класса (а не
инкрементности класса).

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

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

Метрика WMC
дает относительную меру сложности класса. Если считать, что все методы имеют
одинаковую сложность, то это будет просто количество методов в классе.
Существуют рекомендации по сложности методов. Например, М. Лоренц считает, что
средняя длина метода должна ограничиваться 8 строками для
Smalltalk и 24 строками для C++ [45]. Вообще, класс, имеющий
максимальное количество методов среди классов одного с ним уровня, является
наиболее сложным; скорее
всего, он специфичен
для данного приложения и содержит наибольшее количество ошибок.

Метрика 2: Высота дерева наследования DIT (Depth of Inheritance
Tree)

DIT определяется как максимальная длина пути от листа до корня
дерева наследования классов. Для показанной на рис. 14.3 иерархии классов
метрика
DIT равна 3.

Рис. 14.3. Дерево
наследования классов

Соответственно, для отдельного класса DIT, это длина максимального пути от данного класса до
корневого класса в иерархии классов.

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

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

Метрика 3: Количество детей NOC (Number of children)

Подклассы, которые непосредственно подчинены
суперклассу, называются его детьми. Значение
NOC
равно количеству детей, то есть количеству непосредственных наследников класса
в иерархии классов. На рис. 14.3 класс С2 имеет двух детей — подклассы С21 и С22.

С увеличением NOC
возрастает многократность использования, так как наследование — это форма
повторного использования.

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

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

Метрики DIT
и
NOC — количественные характеристики формы и размера структуры
классов. Хорошо структурированная объектно-ориентированная система чаще бывает
организована как лес классов, чем как сверхвысокое дерево. По мнению Г. Буча,
следует строить сбалансированные по высоте и ширине структуры наследования:
обычно не выше, чем 7 ± 2 уровня, и не шире, чем 7 + 2 ветви [22].

Метрика 4: Сцепление между классами объектов СВО (Coupling between object classes)

СВО — это количество сотрудничеств, предусмотренных для класса,
то есть количество классов, с которыми он соединен. Соединение означает, что
методы данного класса используют методы или экземплярные переменные другого
класса.

Другое определение метрики имеет следующий
вид: СВО равно количеству сцеплений класса; сцепление образует вызов метода или
свойства в другом классе.

Данная метрика характеризует статическую
составляющую внешних связей классов.

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

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

СВО для каждого класса должно иметь разумно низкое значение.
Это согласуется с рекомендациями по уменьшению сцепления стандартного
программного обеспечения.

Метрика 5: Отклик для класса RFC (Response For a Class)

Введем вспомогательное определение. Множество
отклика класса
RS — это множество методов, которые
могут выполняться в ответ на прибытие сообщений в объект этого класса. Формула
для определения
RS имеет вид

,

где {Ri} — множество методов, вызываемых методом г, {М} — множество всех методов в классе.

Метрика RFC
равна количеству методов во множестве отклика, то есть равна мощности этого
множества:

RFCcard{RS}.

Приведем другое определение метрики: RFC — это количество методов класса плюс количество методов
других классов, вызываемых из данного класса.

Метрика RFC
является мерой потенциального взаимодействия данного класса с другими классами,
позволяет судить о динамике поведения соответствующего объекта в системе.
Данная метрика характеризует динамическую составляющую внешних связей классов.

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

С ростом RFC
увеличивается сложность класса. Наихудшая величина отклика может использоваться
при определении времени тестирования.

Метрика 6: Недостаток связности в методах LСOM (Lack of Cohesion in Methods)

Каждый метод внутри класса обращается к одному
или нескольким свойствам (экземплярным переменным). Метрика
LCOM показывает, насколько методы не связаны друг с другом через
свойства (переменные). Если все методы обращаются к одинаковым свойствам, то
LCOM = 0.

Введем обозначения:

q      
НЕ СВЯЗАНЫ —
количество пар методов без общих экземплярных переменных;

q      
СВЯЗАНЫ — количество
пар методов с общими экземплярными переменными.

q      
Ij— набор экземплярных переменных, используемых методом Мj

Очевидно, что

НЕ СВЯЗАНЫ = card {Iij | Ii Ij = 0},

СВЯЗАНЫ = card {Iij | Ii Ij 0}.

Тогда формула для вычисления недостатка
связности в методах примет вид

Можно определить метрику по-другому: LCOM — это количество пар методов, не связанных по свойствам
класса, минус количество пар методов, имеющих такую связь.

Рассмотрим примеры применения метрики LCOM.

8.Метрики
Лоренца и Кидда

Коллекция метрик Лоренца и Кидда
— результат практического, промышленного подхода к оценке ОО-проектов [45].

Метрики,
ориентированные на классы

М. Лоренц и Д. Кидд подразделяют метрики,
ориентированные на классы, на четыре категории: метрики размера, метрики
наследования, внутренние и внешние метрики.

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

Метрика 1: Размер класса CS (Class Size)

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

q      
общее количество
операций (вместе с приватными и наследуемыми экземплярными операциями), которые
инкапсулируются внутри класса;

q      
количество свойств
(вместе с приватными и наследуемыми экземплярными свойствами), которые
инкапсулируются классом.

Метрика WMC
Чидамбера и Кемерера также является взвешенной метрикой размера класса.

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

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

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

Рекомендуемое значение CS  20 методов.

Метрика 2: Количество операций, переопределяемых
подклассом,
NOO

(Number of Operations Overridden by
a Subclass)

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

Большие значения NOO
обычно указывают на проблемы проектирования. Ясно, что подкласс должен
расширять операции суперкласса. Расширение проявляется в виде новых имен операций.
Если же
NOО велико, то разработчик нарушает абстракцию суперкласса.
Это ослабляет иерархию классов, усложняет тестирование и модификацию
программного обеспечения.

Рекомендуемое значение NOO  3 методов.

Метрика 3: Количество операций, добавленных подклассом, NOA

(Number of Operations Added by a Subclass)

Подклассы специализируются добавлением
приватных операций и свойств. С ростом
NOA
подкласс удаляется от абстракции суперкласса. Обычно при увеличении высоты
иерархии классов (увеличении
DIT) должно
уменьшаться значение
NOA на нижних уровнях иерархии.

Для рекомендуемых значений CS = 20 и DIT = 6 рекомендуемое
значение
NOA  4 методов (для
класса-листа).

Метрика 4: Индекс специализации SI (Specialization Index)

Обеспечивает грубую оценку степени
специализации каждого подкласса. Специализация достигается добавлением,
удалением или переопределением операций:

SI = (NOO x
уровень) /
Mобщ,

где уровень
номер уровня в иерархии, на котором находится подкласс, Мобщобщее количество
методов класса.

Пример расчета индексов специализации приведен
на рис. 14.5.

Рис. 14.5. Расчет индексов
специализации классов

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

Рекомендуемое значение SI 0,15.

Операционно-ориентированные метрики

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

Метрика 5: Средний размер операции OSAVG (Average Operation Size)

В качестве индикатора размера может
использоваться количество строк программы, однако
LOC-оценки
приводят к известным проблемам. Альтернативный вариант — «количество сообщений, посланных операцией».

Рост значения метрики означает, что
обязанности размещены в классе не очень удачно. Рекомендуемое значение
OSAVG  9.

Метрика 6: Сложность операции ОС (Operation Complexity

Сложность операции может вычисляться с помощью
стандартных метрик сложности, то есть с помощью
LOC
или
FP-оценок, метрики цикломатической сложности, метрики
Холстеда.

М. Лоренц и Д. Кидд предлагают вычислять ОС
суммированием оценок с весовыми коэффициентами, приведенными в табл. 14.5.

Таблица
14.5.
Весовые коэффициенты для метрики ОС

Параметр

Вес

Вызовы функций API

5,0

Присваивания

0,5

Арифметические операции

2,0

Сообщения с параметрами

3,0

Вложенные выражения

0,5

Параметры

0,3

Простые вызовы

7,0

Временные переменные

0,5

Сообщения без параметров

1,0

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

Рекомендуемое значение ОС  65 (для предложенного
суммирования).

Метрика 7: Среднее количество параметров на операцию NPAVG

(Average Number of Parameters per
operation)

Чем больше параметров у операции, тем сложнее
сотрудничество между объектами. Поэтому значение NPAVG должно быть как можно меньшим.

Рекомендуемое значение NPAVG
= 0,7.

Метрики для ОО-проектов

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

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

Метрика 8: Количество описаний сценариев NSS (Number of Scenario Scripts)

Это количество прямо пропорционально
количеству классов, требуемых для реализации требований, количеству состояний
для каждого класса, а также количеству методов, свойств и сотрудничеств.
Метрика
NSS — эффективный индикатор размера программы.

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

Метрика 9: Количество ключевых классов NKC (Number of Key Classes)

Ключевой класс прямо связан с коммерческой
проблемной областью, для которой предназначена система. Маловероятно, что
ключевой класс может появиться в результате повторного использования
существующего класса. Поэтому значение
NKC
достоверно отражает предстоящий объем разработки. М. Лоренц и Д. Кидд
предполагают, что в типовой ОО-системе на долю ключевых классов приходится
20-40% от общего количества классов. Как правило, оставшиеся классы реализуют
общую инфраструктуру (
GUI, коммуникации, базы данных).

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

Метрика 10: Количество подсистем NSUB (NumberofSUBsystem)

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

Рекомендуемое значение: NSUB > 3.

Значения метрик NSS,
NKC, NSUB полезно накапливать как результат
каждого выполненного ОО-проекта. Так формируется метрический базис фирмы, в
который также включаются метрические значения по классами и операциям. Эти
исторические данные могут использоваться для вычисления метрик
производительности (среднее количество классов на разработчика или среднее
количество методов на человеко-месяц). Совместное применение метрик позволяет
оценивать затраты, продолжительность, персонал и другие характеристики текущего
проекта.

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

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

Метрики DIT
и
NOC — количественные характеристики формы и размера структуры
классов. Хорошо структурированная объектно-ориентированная система чаще бывает
организована как лес классов, чем как сверхвысокое дерево. По мнению Г. Буча,
следует строить сбалансированные по высоте и ширине структуры наследования:
обычно не выше, чем 7 ± 2 уровня, и не шире, чем 7 + 2 ветви [22].

Метрика 4: Сцепление между классами объектов СВО (Coupling between object classes)

СВО — это количество сотрудничеств, предусмотренных для класса,
то есть количество классов, с которыми он соединен. Соединение означает, что
методы данного класса используют методы или экземплярные переменные другого
класса.

Другое определение метрики имеет следующий
вид: СВО равно количеству сцеплений класса; сцепление образует вызов метода или
свойства в другом классе.

Данная метрика характеризует статическую
составляющую внешних связей классов.

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

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

СВО для каждого класса должно иметь разумно низкое значение.
Это согласуется с рекомендациями по уменьшению сцепления стандартного
программного обеспечения.

Введем вспомогательное определение. Множество
отклика класса
RS — это множество методов, которые
могут выполняться в ответ на прибытие сообщений в объект этого класса. Формула
для определения
RS имеет вид

где {Ri} — множество методов, вызываемых методом г, {М} — множество всех методов в классе.

Метрика RFC
равна количеству методов во множестве отклика, то есть равна мощности этого
множества:

RFCcard{RS}.

Приведем другое определение метрики: RFC — это количество методов класса плюс количество методов
других классов, вызываемых из данного класса.

Метрика RFC
является мерой потенциального взаимодействия данного класса с другими классами,
позволяет судить о динамике поведения соответствующего объекта в системе.
Данная метрика характеризует динамическую составляющую внешних связей классов.

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

С ростом RFC
увеличивается сложность класса. Наихудшая величина отклика может использоваться
при определении времени тестирования.

Каждый метод внутри класса обращается к одному
или нескольким свойствам (экземплярным переменным). Метрика
LCOM показывает, насколько методы не связаны друг с другом через
свойства (переменные). Если все методы обращаются к одинаковым свойствам, то
LCOM

Понравилась статья? Поделить с друзьями:
  • Количество ошибок на знак характеризует
  • Количество ошибок на 1000 строк кода
  • Количество ошибок ecc скорректированных программным способом
  • Количество ошибок 0 серега пират
  • Количество возможностей ошибки