Основы программирования

Модели реализации объектно-ориентированных программных систем - Локальность данных
Индекс материала
Модели реализации объектно-ориентированных программных систем
Интерфейсы
Компоновка системы
Разновидности компонентов
Моделирование программного текста системы
Основы компонентной объектной модели
Организация интерфейса СОМ
Реализация интерфейса
Серверы СОМ-объектов
Работа с СОМ-объектами
Повторное использование СОМ-объектов
IDL-описаниеи библиотека типа
Диаграммы размещения
Использование диаграмм размещения
Метрики объектно-ориентированных программных систем
Информационная закрытость
Связность объектов
Метрики связности по данным
Метрики связности по методам
Сцепление объектов
Локальность данных
Метрики, ориентированные на классы
Операционно-ориентированные метрики
Метрики для ОО-проектов
Метрики инкапсуляции
Метрики полиморфизма
Все страницы
Локальность данных

 

Локальность данных LD (Locality of Data) — метрика, отражающая качество абстракции, реализуемой классом. Чем выше локальность данных, тем выше самодостаточность класса. Эта характеристика оказывает сильное влияние на такие внешние характеристики, как повторная используемость и тестируемость класса.

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

Будем использовать терминологию языка C++. Обозначим как Mi(1i n) методы класса. В их число не будем включать методы чтения/записи экземплярных переменных. Тогда формулу для вычисления локальности данных можно записать в виде:

,

где:

q       Li(1i n) — множество локальных переменных, к которым имеют доступ методы Mi (прямо или с помощью методов чтения/записи). Такими переменными являются: непубличные экземплярныё переменные класса; унаследованные защищенные экземплярныё переменные их суперклассов; статические переменные, локально определенные в Mi ;

q       Ti(1i n) — множество всех переменных, используемых в Mi, кроме динамических локальных переменных, определенных в Mi.

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

Защищенная экземплярная переменная, которая унаследована классом С, является локальной переменной для его экземпляра (и следовательно, является элементом Li), даже если она не объявлена в классе С. Использование такой переменной методами класса не вредит локальности данных, однако нежелательно, если мы заинтересованы уменьшить значение CDBC.

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

 

В 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 равна количеству методов во множестве отклика, то есть равна мощности этого множества:

RFC – card{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.

Пример 1: В классе имеются методы: M1, M2, М3, М4. Каждый метод работает со своим набором экземплярных переменных:

I1={a, b}; I2={а, с}; I3={х, у}; I4={т, п}.

В этом случае

НЕ СВЯЗАНЫ = card (I13, I14, I23, I24, I34) = 5; СВЯЗАНЫ = card (I12) = 1.

LCOM = 5-1=4.

Пример 2: В классе используются методы: M1, M2, М3. Для каждого метода задан свой набор экземплярных переменных:

I1 = {a,b};I2={a,c};I3={x,y},

НЕ СВЯЗАНЫ = card (I13, I23) = 2; СВЯЗАНЫ = card (I12) = 1,

LCOM = 2- 1 = 1.

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

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

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

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

Недостатком метрики WMC является зависимость от реализации. Приведем пример. Рассмотрим класс, предлагающий операцию интегрирования. Возможны две реализации:

1) несколько простых операций:

Set_interval (min. max)

Setjnethod (method)

Set_precision (precision)

Set_function_to_integrate (function)

Integrate;

2) одна сложная операция:

Integrate (function, min, max. method, precision)

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

.

Для нашего примера WMC2 = 5 и для первой, и для второй реализации. Заметим, для первой реализации WMC = 5, а для второй реализации WMC = 1.

Дополнительно можно определить метрику Среднее число аргументов метода ANAM (Average Number of Arguments per Method):

ANAM = WMC2/WMC.

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

Еще одно предложение — ввести метрику, симметричную метрике LCOM. В то время как формула метрики LCOM имеет вид:

LCOM = max (0, НЕ СВЯЗАНЫ - СВЯЗАНЫ),

симметричная ей метрика Нормализованная NLСОМ вычисляется по формуле:

NLCOM = СВЯЗАНЫ/(НЕ СВЯЗАНЫ + СВЯЗАНЫ).

Диапазон значений этой метрики: 0  NLCOM  1, причем чем ближе NLCOM к 1, тем выше связанность класса.

В наборе Чидамбера-Кемерера отсутствует метрика для прямого измерения информационной закрытости класса. В силу этого была предложена метрика Поведенческая закрытость информации BIH (Behaviourial Information Hiding):

BIH - (WEOC/WIEOC),

где WEOC — взвешенные внешние операции на класс (фактически это WMC);

WIEOC — взвешенные внутренние и внешние операции на класс.

WIEОС вычисляется так же, как и WMC, но учитывает полный набор операций, реализуемых классом. Если BIH = 1, класс показывает другим классам все свои возможности. Чем меньше ВIM, тем меньше видимо поведение класса. BIH может рассматриваться и как мера сложности. Сложные классы, вероятно, будут иметь малые значения BIH, а простые классы — значения, близкие к 1. Если класс с высокой WMC имеет значение BIH, близкое к 1, следует выяснить, почему он настолько видим извне.

Использование метрик Чидамбера-Кемерера

 

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

 

Рис. 14.4. Структура классов для расчета метрик Чидамбера-Кемерера

 

Прокомментируем результаты расчета. Класс Class А имеет три метода (op_al(), ор_а2(), ор_аЗ()), трех детей (Class В, Class С, Class D) и является корневым классом. Поэтому метрики WMC, NOC и DIT имеют, соответственно, значения 3, 3 и 0.

Метрика СВО для класса Class А равна 1, так как он использует один метод из другого класса (метод ор_е() из класса Class E, он вызывается из метода ор_аЗ()). Метрика RFC для класса Class А равна 4, так как в ответ на прибытие в этот класс сообщений возможно выполнение четырех методов (три объявлены в этом классе, а четвертый метод ор_е() вызывается из ор_аЗ()).

Таблица 14.4. Пример расчета метрик Чидамбера-Кемерера

Имя класса

WMC

DIT

NOC

СВО

RFC

LCOM

Class A

3

0

3

1

4

1

Class В

1

1

0

0

1

0

Class С

1

1

0

0

1

0

Class D

2

1

0

2

3

0

Для вычисления метрики LCOM надо определить количество пар методов класса. Оно рассчитывается по формуле

,

где т — количество методов класса.

Поскольку в классе три метода, возможны три пары: op_al( )&ор_а2(), op_al( )&ор_а3() и ор_а2( )&ор_а3(). Первая и вторая пары не имеют общих свойств, третья пара имеет общее свойство (pal). Таким образом, количество несвязанных пар равно 2, количество связанных пар равно 1, и LCOM = 2-1 = 1.

Отметим также, что для класса Class D метрика СВО равна 2, так как здесь используются свойство pal и метод op_f() из других классов. Метрика LCOM в этом классе равна 0, поскольку методы op_dl() и op_d2() связаны по свойству pdl, а отрицательное значение запрещено.

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

 

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