Модульное программирование. Характеристики модуля: размер, связность, сцепление, рутинность
Реферат, 03 Июня 2013, автор: пользователь скрыл имя
Краткое описание
При проектировании достаточно сложного ПО после определения его общей структуры выполняют декомпозицию компонентов в соответствии с выбранным подходом до получения элементов, которые, по мнению проектировщика, в дальнейшей декомпозиции не нуждаются. Основные способы декомпозиции ПО: процедурный (или структурный – по названию подхода) и объектный. Результат процедурной декомпозиции – иерархия подпрограмм (процедур), в которой функции, связанные с принятием решения, реализуются подпрограммами верхних уровней, а непосредственно обработка – подпрограммами нижних уровней. Результат объектной декомпозиции – совокупность объектов, которые затем реализуют как переменные некоторых специально разрабатываемых типов (классов), представляющих собой совокупность полей данных и методов, работающих с этими полями
Прикрепленные файлы: 1 файл
Модульное программирование.docx
— 56.39 Кб (Скачать документ)-
-
-
Для достижения минимальной сложности программного комплекса необходимо добиться такого сопряжения между модулями, чтобы все данные передовались между ними в форме явных и простых параметров.
Виды сцеплений охарактеризуем в порядке уменьшения сцепления.
Сцепление по содержимому — модуль ссылается на данные (содержимое) другого модуля. По сути вызывающий модуль обращаясь к внутренним компонентам вызываемого модуля может не только передавать управления, но и изменять внутренние данные вызываемого модуля или сами коды. В этом варианте вызываемый модуль не является блоком (“черным ящиком”) его содержимое должно учитываться при разработке вызывающего модуля.
Большинство языков программирования высокого уровня делает такое сцепление практически невозможным, однако для языков низкого уровня, например, Ассемблера, такой вид сцепления остается возможным.
2. Сцепление по общей области — модули ссылаются на одну и ту же глобальную структуру данных. При этом основная проблема та, что имена глобальных переменных связывают модули на этапе их кодирования (программирования), а, следовательно, использование таких модулей в других программах или других контекстах затруднено или невозможно вообще. И, кроме того, любые изменения в структуре глобальных данных влекут проверку (тестирование) всех сцепленных по общей области модулей.
Например, функция MaxA, использующая глобальный массив А сцеплена с основной программой по общей области:
Function MaxA: integer;
Var i: word;
Begin
MaxA:= a[Low(a)];
For i:=Low(a) +1 to High(a) do
If a(i)>MaxA then MaxA:=a(i);
End;
3. Сцепление по управлению — один модуль управляет функционированием другого. При этом в вызываемый модуль передается значение управляющей переменной.
Предполагается, что вызывающий модуль “знает” логику работы вызываемого, что уменьшает их независимость. В качестве примера можно привести функцию, которая в зависимости от значения логической переменной возвращает в вызываемую программу либо значение минимального элемента массива, либо значение максимального элемента:
Function MinMax(a,b: integer; flag:boolean): integer;
Begin
If (a>b) and (flag) then MinMax:=a
Else MinMax:=b;
End;
Здесь вызывающий модуль передает в вызываемый некоторый информационный объект (флаг), предназначенный для управления внутренней логикой модуля. Таким способом часто выполняют настройку режимов работы ПО. Подобные настройки снижают наглядность взаимодействия модулей.
4. Сцепление по формату (образцу)
Function MaxEl (a:array of integer): integer;
Var i: word;
Begin
MaxEl:= a[1];
For i:=2 to High(a) do
If a(i)>MaxEl then MaxEl:=a(i);
End;
Такого сцепления, по возможности, следует избегать, поскольку оно создает ненужные связи между модулями.
5. Сцепление по данным — передаваемые параметры — простые (неструктурированные) данные. При небольшом количестве передаваемых параметров этот вид сцепления модулей обеспечивает наилучшие технологические характеристики разрабатываемого ПО. Примером является функция, возвращающая из двух переданных ей целых переменных максимальное:
Function Max(a,b: integer): integer;
Begin
If a>) then Max:=a
Else Max:=b;
End;
Следует иметь в виду, что “модули с памятью”, действия которых зависят от истории вызовов (модуль меняет данные и при следующем вызове работает с другими данными, чем при предыдущем вызове), спользуют сцепление по общей области, что делает их работу в общем случае непредсказуемой. Именно этот вариант используют статические переменные С и С++.
Сцепление модулей
может удовлетворять
Таблица 2. Характеристики сцепления модулей
Тип сцепления |
балл |
устойчивость к ошибкам других модулей |
Нагляд-ность (понят-ность) |
Возмож-ность изменения |
Возможность повторного использования |
По данным |
10 |
хорошая* |
хорошая |
хорошая |
большая |
По образцу |
6 |
средняя |
хорошая* |
средняя |
средняя |
По управлению |
4 |
средняя |
плохая |
плохая |
малая |
По общей области |
3 |
плохая |
плохая |
средняя |
малая |
По содержимому |
1 |
плохая |
плохая |
плохая |
малая |
*-зависит от количества параметров интерфейса.
При разработке модульной структуры ПО следует стремиться к усилению связей в модуле и ослаблению их взаимодействия. В некоторых случаях сцепление модулей можно уменьшить, удалив необязательные связи и структурировав необходимые связи. При этом получение идеальных по прочности и сцеплению модулей не должно быть самоцелью. Нужно понимать, какие проблемы создают неидеальные модули и не забывать описать их в документации.
В литературе /1/ предлагается для оценки приемлемости программного модуля использовать следующие характеристики:
- размер модуля;
- прочность модуля;
- сцепление с другими модулями;
- рутинность модуля (независимость от предыстории обращений к нему).
Размер модуля измеряется числом содержащихся в нем программных операторов или команд. Рекомендуется создавать программные модули размером от нескольких десятков до нескольких сотен операторов.
Прочность и сцепление как основополагающие принципы модульного программирования пояснены выше.
Рутинность интуитивно понятна и означает, что в модуле не должно быть команд, которые изменяются в зависимости от обрабатываемых данных.
Вывод: Подытожим
обсуждение модульного программирования
перечислением принципов
1.Сложность взаимодействия модуля с другими модулями должна быть меньше сложности его внутренней структуры.
2.Хороший модуль снаружи проще, чем изнутри.
3.Хороший модуль проще использовать, чем построить.
Использование модульного программирования существенно упростило разработку программного обеспечения несколькими программистами. Теперь каждый из них мог разрабатывать свои модули независимо, обеспечивая взаимодействие модулей через специально оговоренные межмодульные интерфейсы. Кроме того, модули в дальнейшем без изменений можно было использовать в других разработках, что повысило производительность труда программистов.
Практика показала, что структурный подход в сочетании с модульным программированием позволяет получать достаточно надежные программы, размер которых не превышает 100 000 операторов [10]. Узким местом модульного программирования является то, что ошибка в интерфейсе при вызове подпрограммы выявляется только при выполнении программы (из-за раздельной компиляции модулей обнаружить эти ошибки раньше невозможно). При увеличении размера программы обычно возрастает сложность межмодульных интерфейсов, и с некоторого момента предусмотреть взаимовлияние отдельных частей программы становится практически невозможно. Для разработки программного обеспечения большого объема было предложено использовать объектный подход.