МЕТРИКИ ХОЛСТЕДА

МЕТРИКА УРОВНЯ КОММЕНТИРОВАННОСТИ ПРОГРАММ

Наиболее простой метрикой стилистики и понятности программ является оценка уровня комментированности программы F:

F=Nком/Nстр, (5)

где Nком - количество комментариев в программе; Nстр - количество строк или операторов исходного текста.

Таким образом, метрика F отражает насыщенность программы комментариями.

Исходя из практического опыта, принято считать, что F>=0.1, т. е. на каждые десять строк программы должен приходиться минимум один комментарий. Как показывают исследования, комментарии распределяются по тексту программы неравномерно: в начале программы их избыток, а в середине или в конце - недостаток. Это объясняется тем, что в начале программы, как правило, расположены операторы описания идентификаторов, требующие более "плотного" комментирования. Кроме того, в начале программы также расположены "шапки", содержащие общие сведения об исполнителе, характере, функциональном назначении программы и т. п. Такая насыщенность компенсирует недостаток комментариев в теле программы, и поэтому формула (5) недостаточно точно отражает комментированность функциональной части текста программы.

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

Fi = sign (Nком/Nстр - 0.1),

при этом

n

F=Сумма(Fi).

i=1

Уровень комментированности программы считается нормальным, если выполняется условие: F=n. В противном случае какой-либо фрагмент программы дополняется комментариями до номинального уровня.

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

1. Для измерения теоретической длины программы N^ М. Холстед вводит аппроксимирующую формулу:

N^ = n1*log2(n1) + n2*log2(n2), (6)

где n1 - словарь операторов;

n2 - словарь операндов программы.

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

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

б) присутствуют тождественные выражения, решающие совершенно одинаковые задачи;

в) одной и той же переменной назначаются различные имена и т. п.

Подобные ситуации приводят к изменению N без изменения n.

М. Холстед утверждает, что для стилистически корректных программ отклонение в оценке теоретической длины N^ от реальной N не превышает 10%.

Мы предлагаем использовать N^ как эталонное значение длины программы со словарем n. Длина корректно составленной программы N, т. е. программы, свободной от избыточности и имеющей словарь n, не должна отклоняться от теоретической длины программы N^ более чем на 10%. Таким образом, измеряя n1, n2, N1 и N2 и сопоставляя значения N и N^ для некоторой программы, при более чем 10%-ном отклонении можно говорить о наличии в программе стилистических ошибок, т. е. несовершенств.

На практике N и N^ часто существенно различаются.

2. Другой характеристикой, принадлежащей к метрикам корректности программ, по М. Холстеду, является уровень качества программирования L (уровень программы):

L=V*/V, (7)

где V и V* определяется соответственно выражениями (2) и (3).

Исходным для введения этой характеристики является предположение о том, что при снижении стилистического качества программирования уменьшается содержательная нагрузка на каждый компонент программы и, как следствие, расширяется объем реализации исходного алгоритма. Учитывая это, можно оценить качество программирования на основании степени расширения текста относительно потенциального объема V*. Очевидно, для идеальной программы L=1, а для реальной - всегда L<1.

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

L^ = 2*n2 / (n1*N2).

4. Располагая характеристикой L^, Холстед вводит характеристику I, которую рассматривает как интеллектуальное содержание конкретного алгоритма, инвариантное по отношению к используемым языкам реализации:

I = L^ * V. (8)

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

I = L^V = LV = V*V/V = V*.

Эквивалентность I и V* свидетельствует о том, что мы имеем дело с характеристикой информативности программы.

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

1) осмысление предложения известного алгоритма;

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

Используя эту формализацию в методике Холстеда, можно сказать, что написание программы по заранее известному алгоритму есть N^-кратная выборка операторов и операндов из словаря программы n, причем число сравнений (по аналогии с алгоритмами сортировки) составит log2(n).

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

E = N^ * log2(n/L). (9)

 

Таким образом, E характеризует число требуемых элементарных решений при написании программы.

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

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

E' = N * log2(n/L).

Характеристика E' введена исходя мз предположения, что интеллектуальные усилия на написание и восприятие программы очень близки по своей природе. Однако если при написании программы стилистические погрешности в тексте практически не должны отражаться на интеллектуальной трудоемкости процесса, то при попытке понять такую программу их присутствие может привести к серьезным осложнениям. Эта посылка достаточно хорошо согласуется с нашими выводами относительно взаимосвязи N и N^, изложенными выше.

Преобразуя формулу (9) с учетом выражений (2) и (7), получаем

E = V * V / V*.

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

МЕТРИКА ИЗМЕНЕНИЯ ДЛИНЫ ПРОГРАММНОЙ ДОКУМЕНТАЦИИ

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

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

Предположим, что документация изменяется в дискретные моменты времени t(i), i=1,2,...,n. Тогда в любой момент времени t(i) текущая длина документа l(i) может быть определена как

l(i) = l(i-1) + a(i) - b(i); l(0) = 0,

где l(i-1) - длина документа в предыдущий момент времени; a(i) - добавляемая часть документа; b(i) - исключаемая часть документа.

Далее вводится d(i), представляющая собой отклонение текущей длины документа l(i) от конечного значения l(n):

d(i) = l(n) - l(i).

Затем рассчитывается интеграл по модулю этого отклонения на интервале от t(i) до t(n), представленный в виде суммы:

n-1

H(n) = Сумма |d(i)| * (t(i+1) - t(i)). (10)

i=1

Значение H(n) представляет собой оценку переходного процесса для интервала времени от t(1) до t(n). Однако H(n) не учитывает изменений типа a(i)=b(i), хотя они, бесспорно, влияют на ход дальнейшего процесса.

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

Интеграл a(i)*e^(-L^(-1*(t-t(i))))dt = L*L(i) = L*b(i), L>0. (11)

t(i)

Таким образом, оценка длины документа пропорциональна значению импульсного изменения длины a(i)=b(i) с коэффициентом пропорциональности L.

В принципе импульсное изменение длины документа присутствует и при a(i)<>b(i). Поэтому с учетом (11) автор метрики преобразует выражение (10) к виду

n-1

H'(n) = Сумма [ |d(i)| * (t(i+1)-t(i)) + L*c(i) ], (12)

i=1

причем c(i) = min {a(i), b(i)}.

Если в процессе работы значения a(i) и b(i) неконтролируемы, импульсное изменение длины учесть нельзя. Тогда c(i)=0, и выражение (12) вырождается в (10). Используя конечное значение длины документа, можно записать

H(n)'' = H(n)' / l(n).