Сцепление модулей

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

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

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

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

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

Глобальные данные усложняют и восприятие программы. Рассмот­рим следующий фрагмент:

WHILE A DO

BEGIN

L (X,Y,Z);

M (X,Y);

N (W,Z);

P (Z,X,Y);

END;

END;

Если А не является глобальной переменной и если другие неудачные приемы кодирования (такие как совмещение А с W, X, Y или Z) не исполь­зу­ются, то можно утверждать, что этот цикл никогда не закончится. Если А – глобальная переменная, то сразу нельзя определить, закончится ли вы­полне­ние цикла. Придется исследовать внутреннее устройство модулей L, М, N и Р, а также всех модулей, которые им подчинены, чтобы понять только этот цикл DO!

Группа модулей сцеплена по внешним данным, если они ссылаются на один и тот же глобальный элемент данных (переменную, имеющую единственное поле). Например, модули Delphi сцеплены друг с другом по внешним данным с помощью глобальных переменных.

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

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

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

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

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

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

Как и в случае с прочностью модуля, сцепление влияет и на другие, не рассматриваемые здесь специально свойства программы (на адаптируе­мость, сложность тестирования, возможность повторного использования модулей, простоту или сложность мультипрограммирования [11]).

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

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

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

1. Сложность взаимодействия модуля с другими модулями должна быть меньше сложности его внутренней структуры.

2. Хороший модуль снаружи проще, чем внутри.

3. Хороший модуль проще использовать, чем построить.

Наши рекомендации