Файл: Иванова Г.С. Технология программирования.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 20.11.2019

Просмотров: 9464

Скачиваний: 184

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

2.

ПРИЕМЫ

ОБЕСПЕЧЕНИЯ

ТЕХНОЛОГИЧНОСТИ

  

ПРОГРАММНЫХ

ПРОДУКТОВ

В

условиях

индустриального

подхода

к

разработке

и

сопровождению

программного

обеспечения

особый

вес

приобретают

технологические

характеристики

разрабатываемых

программ

Для

обеспечения

необходимых

технологических

свойств

применяют

специальные

технологические

приемы

и

следуют

определенным

методикам

сформулированным

всем

предыдущим

опытом

создания

программного

обеспечения

К

таким

приемам

и

методикам

относят

правила

декомпозиции

методы

проектирования

программирования

и

контроля

качества

которые

под

общим

названием

 "

структурный

подход

к

программированию

» 

были

сформулированы

еще

в

60-

х

голах

 XX 

в

В

его

основу

были

положены

следующие

основные

концепции

нисходящая

разработка

модульное

программирование

структурное

программирование

сквозной

структурный

контроль

2.1. 

Понятие

технологичности

программного

обеспечения

Под

технологичностью

понимают

качество

проекта

программного

продукта

от

которого

зависят

трудовые

и

материальные

затраты

на

его

реализацию

и

последующие

модификации

Хороший

проект

сравнительно

быстро

и

легко

кодируется

тестируется

отлаживается

и

модифицируется

Из

опыта

нескольких

поколений

разработчиков

программного

обеспечения

известно

что

технологичность

программного

обеспечения

определяется

проработанностью

его

моделей

уровнем

независимости

модулей

стилем

программирования

и

степенью

повторного

использования

кодов

Чем

лучше

проработана

модель

разрабатываемого

программного

обеспечения

тем

четче

определены

подзадачи

и

структуры

данных

хранящие

входную

промежуточную

и

выходную

информацию

тем

проще

их

проектирование

и

реализация

и

меньше

вероятность

ошибок

для

исправления

которых

потребуется

существенно

изменять

программу

Чем

выше

независимость

модулей

тем

их

легче

понять

реализовывать

модифицировать

а

также

находить

в

них

ошибки

и

исправлять

их

Стиль

программирования

под

которым

понимают

стиль

оформления

программ

и

их

«

структурность

», 

также

существенно

влияет

на

читаемость

программного

кода

и

количество

ошибок

программирования

Кризис

 60-

х

годов

 XX 

в

был

вызван

в

том

числе

и

стилем

программирования

при

котором

программа

напоминала

клубок

спутанных

ниток

или

блюдо

спагетти

и

отсутствием

языковых

конструкций

поддержки

 «

структурного

» 

стиля

Увеличение

степени

повторного

использования

кодов

предполагает

как

использование

ранее

разработанных

библиотек

подпрограмм

или

классов

так

и

унификацию

кодов

текущей

разработки

Причем

для

данного

критерия

ситуация

не

так

однозначна

как

в

предыдущих

случаях

если

степень

повторного

использования

кодов

повышается

искусственно

  (

например

путем

разработки

  «

суперуниверсальных

» 

процедур

), 

то

технологичность

проекта

может

существенно

снизиться

Как

следует

из

определения

высокая

технологичность

проекта

особенно

важна

если

разрабатывается

программный

продукт

рассчитанный

на

многолетнее

интенсивное

использование

или

необходимо

обеспечить

повышенные

требования

к

его

качеству

2.2. 

Модули

и

их

свойства

При

проектировании

достаточно

сложного

программного

обеспечения

после

определения

его

общей

структуры

выполняют

декомпозицию

компонентов

в

соответствии

с

выбранным

подходом

до

получения

элементов

которые

по

мнению

проектировщика

в

дальнейшей

декомпозиции

не


background image

нуждаются

Как

уже

упоминалось

раньше

в

настоящее

время

используют

два

способа

декомпозиции

разрабатываемого

программного

обеспечения

связанные

с

соответствующим

подходом

процедурный

 (

или

структурный

 - 

по

названию

подхода

); 

объектный

Примечание

.

Помимо

указанных

способов

декомпозиции

в

теории

программирования

определяют

и

другие

способы

декомпозиции

логическую

 - 

на

факты

и

правила

продукционную

 - 

на

правила

продукции

и

т

п

Эти

способы

декомпозиции

используют

в

языках

искусственного

интеллекта

поэтому

в

настоящем

учебнике

они

рассматриваться

не

будут

Результатом

процедурной

декомпозиции

является

иерархия

подпрограмм

  (

процедур

), 

в

которой

функции

связанные

с

принятием

решения

реализуются

подпрограммами

верхних

уровней

а

непосредственно

обработка

 - 

подпрограммами

нижних

уровней

Это

согласуется

с

принципом

вертикального

управления

который

был

сформулирован

вместе

с

другими

рекомендациями

структурного

подхода

к

программированию

Он

также

ограничивает

возможные

варианты

передачи

управления

требуя

чтобы

любая

подпрограмма

возвращала

управление

той

подпрограмме

которая

ее

вызвала

Результатом

объектной

декомпозиции

является

совокупность

объектов

которые

затем

реализуют

как

переменные

некоторых

специально

разрабатываемых

типов

  (

классов

), 

представляющих

собой

совокупность

полей

данных

и

методов

работающих

с

этими

полями

Таким

образом

при

любом

способе

декомпозиции

получают

набор

связанных

с

соответствующими

данными

подпрограмм

которые

в

процессе

реализации

организуют

в

модули

Модули

.

Модулем

называют

автономно

компилируемую

программную

единицу

Термин

«

модуль

» 

традиционно

используется

в

двух

смыслах

Первоначально

когда

размер

программ

был

сравнительно

невелик

и

все

подпрограммы

компилировались

отдельно

под

модулем

понималась

подпрограмма

т

е

последовательность

связанных

фрагментов

программы

обращение

к

которой

выполняется

по

имени

.

Со

временем

когда

размер

программ

значительно

вырос

и

появилась

возможность

создавать

библиотеки

ресурсов

констант

переменных

описаний

типов

классов

и

подпрограмм

термин

  «

модуль

» 

стал

использоваться

и

в

смысле

автономно

компилируемый

набор

программных

ресурсов

Данные

модуль

может

получать

и

/

или

возвращать

через

общие

области

памяти

или

параметры

Первоначально

к

модулям

  (

еще

понимаемым

как

подпрограммы

предъявлялись

следующие

требования

отдельная

компиляция

одна

точка

входа

одна

точка

выхода

соответствие

принципу

вертикального

управления

возможность

вызова

других

модулей

небольшой

размер

 (

до

 50-60 

операторов

языка

); 

независимость

от

истории

вызовов

выполнение

одной

функции

Требования

одной

точки

входа

одной

точки

выхода

независимости

от

истории

вызовов

и

соответствия

принципу

вертикального

управления

были

вызваны

тем

что

в

то

время

из

-

за

серьезных

ограничений

на

объем

оперативной

памяти

программисты

были

вынуждены

разрабатывать

программы

с

максимально

возможной

повторяемостью

кодов

В

результате

подпрограммы

имеющие

несколько

точек

входа

и

выхода

были

не

только

обычным

явлением

но

и

считались

высоким

классом

программирования

Следствием

же

было

то

что

программы

было

очень

сложно

не

только

модифицировать

но

и

понять

а

иногда

и

просто

полностью

отладить

Со

временем

когда

основные

требования

структурного

подхода

стали

поддерживаться

языками

программирования

и

под

модулем

стали

понимать

отдельно

компилируемую

библиотеку

ресурсов

требование

независимости

модулей

стало

основным


background image

Практика

показала

что

чем

выше

степень

независимости

модулей

тем

легче

разобраться

в

отдельном

модуле

и

всей

программе

и

соответственно

тестировать

отлаживать

и

модифицировать

ее

меньше

вероятность

появления

новых

ошибок

при

исправлении

старых

или

внесении

изменений

в

программу

т

е

вероятность

появления

 «

волнового

» 

эффекта

проще

организовать

разработку

программного

обеспечения

группой

программистов

и

легче

его

сопровождать

Таким

образом

уменьшение

зависимости

модулей

улучшает

технологичность

проекта

Степень

независимости

модулей

  (

как

подпрограмм

так

и

библиотек

оценивают

двумя

критериями

сцеплением

и

связностью

Сцепление

модулей

.

Сцепление

является

мерой

взаимозависимости

модулей

которая

определяет

насколько

хорошо

модули

отделены

друг

от

друга

Модули

независимы

если

каждый

из

них

не

содержит

о

другом

никакой

информации

Чем

больше

информации

о

других

модулях

хранит

модуль

тем

больше

он

с

ними

сцеплен

Различают

пять

типов

сцепления

модулей

по

данным

по

образцу

по

управлению

по

общей

области

данных

по

содержимому

Сцепление

по

данным

предполагает

что

модули

обмениваются

данными

представленными

скалярными

значениями

При

небольшом

количестве

передаваемых

параметров

этот

тип

обеспечивает

наилучшие

технологические

характеристики

программного

обеспечения

Например

функция

Мах

предполагает

сцепление

по

данным

через

параметры

скалярного

типа

 
Function Max(a, b: integer): integer; 
  begin 

  if a>b then Max:=a  
             else Max: =b;  
end; 

Сцепление

по

образцу

предполагает

что

модули

обмениваются

данными

объединенными

в

структуры

Этот

тип

также

обеспечивает

неплохие

характеристики

но

они

хуже

чем

у

предыдущего

типа

так

как

конкретные

передаваемые

данные

 «

спрятаны

» 

в

структуры

и

потому

уменьшается

  «

прозрачность

» 

связи

между

модулями

Кроме

того

при

изменении

структуры

передаваемых

данных

необходимо

модифицировать

все

использующие

ее

модули

Так

функция

 MaxEl, 

описанная

ниже

предполагает

сцепление

по

образцу

  (

параметр

а

 - 

открытый

массив

). 

 
Function MaxEl(a:array of integer): integer;  
Var i:\vord; 
  begin 
             MaxEl: =a [O]; 
              for i: =l to High (a) do 
                    if a [i]>MaxEl then MaxEl: =a [i]; 
end; 

При

сцеплении

по

управлению

один

модуль

посылает

другому

некоторый

информационный

объект

  (

флаг

), 

предназначенный

для

управления

внутренней

логикой

модуля

Таким

способом

часто

выполняют

настройку

режимов

работы

программного

обеспечения

Подобные

настройки

также

снижают

наглядность

взаимодействия

модулей

и

потому

обеспечивают

еще

худшие

ха

-

рактеристики

технологичности

разрабатываемого

программного

обеспечения

по

сравнению

с


background image

предыдущими

типами

связей

Например

функция

 MinMax 

предполагает

сцепление

по

управлению

так

как

значение

параметра

 flag 

влияет

на

логику

программы

если

функция

 MinMax 

получает

значение

параметра

flag, 

равное

 true, 

то

возвращает

максимальное

значение

из

двух

а

если

 false, 

то

минимальное

 
Function MinMax (a, b: integer; f!ag:boo!ean): integer;  
 begin 

     if(a>b) and (flag) then MinMax: =a 

else MinMax: =b;  

end; 

Сцепление

по

общей

области

данных

предполагает

что

модули

работают

с

общей

областью

данных

Этот

тип

сцепления

считается

недопустимым

поскольку

программы

использующие

данный

тип

сцепления

очень

сложны

для

понимания

при

сопровождении

программного

обеспечения

ошибка

одного

модуля

приводящая

к

изменению

общих

данных

может

проявиться

при

выполнении

другого

модуля

что

существенно

усложняет

локализацию

ошибок

при

ссылке

к

данным

в

общей

области

модули

используют

конкретные

имена

что

уменьшает

гибкость

разрабатываемого

программного

обеспечения

       

Например

функция

МахА

использующая

глобальный

массив

А

сцеплена

с

основной

программой

по

общей

области

 
Function MaxA: integer; 
 Var i:word; 
  begin 
                

МахА

: =a[Low(a)];  

                 for i: = Low (a) + l to High(a) do 
                       if a [i]>MaxA then MaxA: = a [i]; 
end; 

Следует

иметь

в

виду

что

 «

подпрограммы

с

памятью

», 

действия

которых

зависят

от

истории

вызовов

используют

сцепление

по

общей

области

что

делает

их

работу

в

общем

случае

непредсказуемой

Именно

этот

вариант

используют

статические

переменные

С

и

 C++. 

В

случае

сцепления

по

содержимому

один

модуль

содержит

обращения

к

внутренним

компонентам

другого

 (

передает

управление

внутрь

читает

и

/

или

изменяет

внутренние

данные

или

сами

коды

), 

что

полностью

противоречит

блочно

-

иерархическому

подходу

Отдельный

модуль

в

этом

случае

уже

не

является

блоком

 («

черным

ящиком

»): 

его

содержимое

должно

учитываться

в

процессе

разработки

другого

модуля

Современные

универсальные

языки

процедурного

программирования

например

 Pascal, 

данного

типа

сцепления

в

явном

виде

не

поддерживают

но

для

языков

низкого

уровня

например

Ассемблера

такой

вид

сцепления

остается

возможным

В

табл

. 2.1 

приведены

характеристики

различных

типов

сцепления

по

экспертным

оценкам

[21, 30]. 

Допустимыми

считают

первые

три

типа

сцепления

так

как

использование

остальных

приводит

к

резкому

ухудшению

технологичности

программ

.  

Как

правило

модули

сцепляются

между

собой

несколькими

способами

Учитывая

это

качество

программного

обеспечения

принято

определять

по

типу

сцепления

с

худшими

характеристиками

Так

если

использовано

сцепление

по

данным

и

сцепление

по

управлению

то

определяющим

считают

сцепление

по

управлению

В

некоторых

случаях

сцепление

модулей

можно

уменьшить

удалив

необязательные

связи

и

структурировав

необходимые

связи

Примером

может

служить

объектно

-

ориентированное

программирование

в

котором

вместо

большого

количества

параметров

метод

неявно

получает

адрес

области

  (

структуры

), 

в

которой

расположены

поля

объекта

и

явно

-

дополнительные

параметры

В

результате

модули

оказываются

сцепленными

по

образцу


background image

Таблица

 2.1 

Тип

сцепления

Сцепление

балл

Устойчивость

к

ошибкам

других

модулей

Наглядность

(

понятность

Возможность

изменения

Вероятность

повторного

использования

По

данным

По

образцу

По

управлению

По

общей

области

По

содержимому

10 

Хорошая

 * 

Средняя

Средняя

Плохая

Плохая

   

Хорошая

Хорошая

 * 

Плохая

Плохая

Плохая

Хорошая

Средняя

Плохая

Средняя

Плохая

  

Большая

Средняя

Малая

Малая

Малая

  

Связность

модулей

.

Связность

 - 

мера

прочности

соединения

функциональных

и

информационных

объектов

внутри

одного

модуля

Если

сцепление

характеризует

качество

отделения

модулей

то

связность

характеризует

степень

взаимосвязи

элементов

реализуемых

одним

модулем

Размещение

сильно

связанных

элементов

в

одном

модуле

уменьшает

межмодульные

связи

и

соответственно

взаимовлияние

модулей

В

то

же

время

помещение

сильно

связанных

элементов

в

разные

модули

не

только

усиливает

межмодульные

связи

но

и

усложняет

понимание

их

взаимодействия

Объединение

слабо

связанных

элементов

также

уменьшает

технологичность

модулей

так

как

такими

элементами

сложнее

мысленно

манипулировать

Различают

следующие

виды

связности

 (

в

порядке

убывания

уровня

): 

функциональную

последовательную

информационную

 (

коммуникативную

); 

процедурную

временную

логическую

случайную

При

функциональной

связности

все

объекты

модуля

предназначены

для

выполнения

одной

функции

  (

рис

. 2.1, 

а

): 

операции

объединяемые

для

выполнения

одной

функции

или

данные

связанные

с

одной

функцией

Модуль

элементы

которого

связаны

функционально

имеет

четко

определенную

цель

при

его

вызове

выполняется

одна

задача

например

подпрограмма

поиска

минимального

элемента

массива

Такой

модуль

имеет

максимальную

связность

следствием

которой

являются

его

хорошие

технологические

качества

простота

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

модификации

и

сопровождения

Именно

с

этим

связано

одно

из

требований

структурной

декомпозиции

  «

один

модуль

 - 

одна

между

модулями

 - 

библиотеками

ресурсов

Например

если

при

проектировании

текстового

редактора

предполагается

функция

редактирования

то

лучше

организовать

модуль

 - 

библиотеку

функций

редактирования

чем

поместить

часть

функций

в

один

модуль

а

часть

в

другой

При

последовательной

связности

функций

выход

одной

функции

служит

исходными

данными

для

другой

функции

 (

рис

. 2.1, 

б

). 

Как

правило

такой

модуль

имеет

одну

точку

входа

т

е

реализует

одну

подпрограмму

выполняющую

две

функции

Считают

что

данные

используемые

последовательными

функциями

также

связаны

последовательно

Модуль

с

последовательной

связностью

функций

можно

разбить

на

два

или

более

модулей

как

с

последовательной

так

и

с

функциональной

связностью

Такой

модуль

выполняет

несколько

функций

и

следовательно

его

технологичность

хуже

сложнее

организовать

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

а

при

выполнении

модификации

мысленно

приходится

разделять

функции

модуля