Технология разработки ПО. Требования к современным технологиям разработки ПО. Этапы проектирования сложных программных средств. Использование абстракций и спецификаций при разработке программ.

Урок 18.

Предмет: Технология разработки программных продуктов.

Тема : Фазы процесса разработки ПО.Абстракции.

 

Цели:

Образовательная

Ознакомление с фазами процесса разработки ПО. Абстракции.

Развивающая:

Развивать умение слушать других, делать выводы и обобщать полученные знания

Воспитательная:

Воспитывать чувство значимости предмета в профессиональной деятельности, аккуратности в работе

Межпредметные связи:

-         Английский язык

-         Операционные системы

-         Информационные технологии

-         Основы алгоритмизации и программирования

Оборудование: доска, мел, письменные принадлежности, проектор, ПК

Тип урока: комбинированный

Метод обучения: Объяснительно иллюстративный

Ход урока:

1.Организационный момент

         - Проверка готовности кабинета

         - Объявление темы

2. Постановка цели урока

3.Повторение пройденного материала

    Функциональные требования

    Эксплуатационные требования

    Выбор архитектуры программного обеспечения

 

4.Сообщение новых знаний

    Технология разработки ПО

    Требования к современным технологиям разработки ПО

    Этапы проектирования сложных программных средств

    Использование абстракций и спецификаций при разработке программ

 

5. Восприятие и осознание учащимися нового материала

6. Осмысление обобщение и систематизация знаний

7. Подведение итогов урока и  постановка домашнего задания

   Выучить содержимое темы

Орлов С.А. стр. С.36-40

        Ответить на вопросы:

 

1.2. Технология разработки ПО

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

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

1.3. Требования к современным технологиям разработки ПО

  1. ТРПО должна обеспечивать отторжимость ПО от разработчика. Это необходимо для грамотного сопровождения, модификации и воспроизводства ПП в других условиях эксплуатации.
  2. ТРПО и средства ее поддержки должны обеспечивать целенаправленную работу прежде всего коллектива программистов, а не отдельных исполнителей. Основные части любой современной технологии: сетевое планирование, система формализованных поручений и эффективный контроль за их исполнением.
  3. ТРПО должна обеспечивать автоматизацию всех этапов работы коллектива программистов.
  4. ТРПО не должна быть связана с языком программирования, т.к. не он является определяющим звеном ТРПО.
  5. ТРПО должна быть простой в освоении, с автоматизированными средствами подсказки и обучения.
  6. ТРПО должна иметь средства фиксации всех действий в процессе изготовления программного продукта (автоматизированное хранение системных журналов, дневников разработки). Это необходимо для восстановления состояния процесса разработки на любом его этапе (при комплексной отладке и сопровождении ПО).
  7. ТРПО должна обеспечивать пользователю ПП доступ к документации на продукт (техническому описанию, инструкции пользователю, инструкции по эксплуатации и т.п.) на магнитных носителях. Доступ должен быть простым и автоматизированным. Работа пользователя должна обеспечиваться информационно-справочной системой.

1.4. Этапы проектирования сложных программных средств

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

1) программы с малой длительностью эксплуатации – создаются в основном для решения научных и инженерных задач, для получения конкретных результатов вычислений; они содержат от 1 до 10000 команд, разрабатываются одним специалистом или малой группой, не предназначены для тиражирования и передачи; жизненный цикл таких программ не превышает 3-х лет, время эксплуатации практически равно 0;

2) программы с большой длительностью эксплуатации – создаются для регулярной обработки информации и управления; такие программы содержат от 1 до 1000000 команд, обладают свойством независимости от разработчика, возможностью модификации в процессе сопровождения и использования различными программистами, допускают тиражирование, сопровождаются документацией как промышленное изделие, являются отчуждаемыми; жизненный цикл таких программ составляет 10 – 20 лет, из них 70 – 90 % занимает время эксплуатации.

Все последующее изложение ориентировано на ПО второй группы.

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

Фаза жизненного цикла

Стадия разработки
по ГОСТ 19.102-77 ЕСПД

Состояние ПО
в конце фазы

1. Системный анализ:

а) выработка требований;

б) разработка спецификаций

Разработка технического задания

Функциональная

архитектура

2. Проектирование:

а) проектирование архитектуры;

б) детальное проектирование

 

Эскизное проектирование

Техническое проектирование

 

 

Системная архитектура

3. Реализация (конструирование):

а) кодирование;

б) интеграция;

в) тестирование (сертификация)

Рабочее проектирование

 

 

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

Программное средство

4. Внедрение:

а) изготовление;

б) установка на ЭВМ пользователя

Внедрение

 

Программный продукт

Программное обеспечение

5. Эксплуатация

Эксплуатация

 

6. Сопровождение

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

 

1.5. Содержание основных фаз жизненного цикла ПО

Фаза 1. Системный анализ. Выявляются свойства, которыми должна обладать система в окончательном варианте, т.е. создается замысел системы. Разработчик определяет подробную картину внешних свойств готового изделия: описываются функции, которые будет выполнять система; характеристики интерфейса, обеспечиваемого системой. Во время этой фазы принимаются решения относительно размеров, времени отклика, производительности и других параметров системы. Определение осуществляется посредством двух основных категорий – требований (описаний необходимых свойств) и спецификаций (описаний объектов, обладающих этими свойствами).

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

Спецификация – описание на языке разработчика внешне известных характерных особенностей поведения системы. Функциональная спецификация включает в себя:

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

Фаза 2. Проектирование. Входной информацией для проектирования являются спецификации, написанные по требованиям пользователя.

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

Наряду с описанием общей структуры, результатом этапа являются спецификации на модули, состоящие из следующих секций.

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

Неформальное описание. Общий обзор действий модуля с глубиной детализации, достаточной для понимания того, что должен делать модуль.

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

Вход/выход. Описание формальных параметров, значения функции, классов переменных (глобальных, локальных и известных только нескольким модулям) и системных констант.

Алгоритм. Эта часть модуля описывает действия модуля. Они должны быть ясны разработчику. Алгоритм должен быть структурирован.

Примечания. Комментарии: временные характеристики, необычные ситуации, приводящие к ошибкам и т.п.

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

Фаза 3. Реализация. Перевод проекта в форму программы для конкретной ЭВМ, сборка системы, ее прогон при тестовых и нормальных условиях для подтверждения ее работы в соответствии с документом, описывающим спецификации.

Фаза 4. Внедрение. Полное, упорядоченное, координируемое пользователем приобщение к реальной среде новой или измененной системы. Подтверждение соответствия требованиям.

Фаза 5. Эксплуатация. Функционирование ПО на ЭВМ заказчика, оценка работающей системы и поддержание ее работы в приемлемых границах.

Фаза 6. Сопровождение. При выпуске программы как товарной продукции для общего пользования завершающей фазой является сопровождение, которое заключается в следующих действиях: обнаружение и исправление ошибок; добавление новых функций и модификация существующих; тиражирование и перенос на другие вычислительные средства; улучшение показателей работы.

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

 

3. Использование абстракций и спецификаций
при разработке программ

3.1. Общие положения

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

1) каждая подзадача имеет один и тот же уровень рассмотрения;

2) каждая подзадача может быть решена независимо;

3) полученные решения могут быть объединены вместе.

Эффективным способом декомпозиции является абстракция – игнорирование ряда подробностей для сведения задачи к более простой.

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

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

Можно определить два различных вида абстракции, каждый из которых использует оба способа абстракции:

1) процедурная абстракция (ПА) позволяет расширить заданную некоторым языком виртуальную машину новой операцией;

2) абстракция данных (АД) позволяет добавить к виртуальной машине новые типы данных, состоящие из набора объектов и набора операций, характеризующих поведение этих объектов.

3.2. Процедурная абстракция

3.2.1. Понятие и преимущества процедурной абстракции

Процедура выполняет преобразование входных параметров в выходные.

Процедура есть отражение набора значений входных аргументов в выходной набор результатов с возможной модификацией входных значений. Набор входных или выходных значений (или оба) могут быть пустыми.

Процедура объединяет в себе абстракцию через параметризацию и абстракцию через спецификацию, т.к. абстрагирует отдельную операцию. В АП мы абстрагируемся от конкретных используемых данных. АП определяется в терминах формальных параметров. Фактические данные связываются с этими параметрами при использовании абстракции. Значения конкретных данных несущественны, важны лишь их количество и тип.

Параметризация позволяет обобщить модуль, в результате чего уменьшается размер программы и, следовательно, объем модификаций.

В АС существенным является «поведение» (что делается), а несущественным – реализация (как это делается). Это позволяет переходить к другой реализации без внесения изменений в программу, использующую эту реализацию. Реализации могут быть выполнены даже на различных языках, если типы данных в этих языках трактуются одинаково. АС наделяет программу двумя свойствами: локальностью и модифицируемостью.

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

Модифицируемость – изменения в реализации абстракции не влияют на программу в целом, если спецификации абстракций остаются прежними.

3.2.2. Спецификация процедурной абстракции

Спецификации могут быть формальными и неформальными. Формальные спецификации имеют точно определенное значение. Неформальные спецификации легче читать и понимать, но точное их содержание не всегда может быть установлено. Считается, что языком спецификаций может быть язык более высокого уровня, чем тот, на котором должна быть написана программа. Для спецификации программ будем использовать язык CLU (cluster) – предвестник языка АДА.

Спецификация процедуры состоит из заголовка и описания функции. Заголовок содержит имя процедуры, количество, порядок и типы входных и выходных параметров. Информация в заголовке чисто синтаксическая. В семантической части описывается смысл выполняемых процедурой действий на естественном языке, возможно расширенном привычными математическими обозначениями. Семантическая часть спецификации состоит из трех предложений: requires (требует), modifies (модифицирует), effects (выполняет). Предложения requires и modifies могут быть опущены. Шаблон спецификации процедурной абстракции:

Pname=proc(входные параметры) returns(выходные параметры)

requires список ограничений

modifies список модифицируемых входных параметров

effects описание работы процедуры

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

Предложение modifies задает список имен входных параметров, модифицируемых процедурой. Если входные параметры не указаны, то это предложение может быть опущено.

Предложение effects описывает работу процедуры, определяет выходные значения и модификации над входными параметрами. Предложение effects составляется исходя из предположения, что требования предложения requires удовлетворены. В том случае, когда требования requires не удовлетворены, о поведении процедуры ничего не сообщается.

Примеры спецификаций процедурных абстракций:

Concat=proc(a,b: String) returns(ab: String)

effects По возврату ab есть новая строка, содержащая символы из a (в порядке их расположения в a), за которыми следуют символы из b (в порядке их расположения в b).

RemoveDupls=proc(a: array[real])

modifies a

effects Удаляет из массива a все повторяющиеся элементы, порядок следования оставшихся элементов может измениться.

Search=proc(a:array[real],x:real) returns(i:int)

requires Массив a упорядочен по возрастанию.

effects Если элемент x принадлежит массиву a, то возвращается значение i такое, что a[i]=x; в противном случае возвращается значение i на единицу большее, чем значение верхней границы массива a.

3.2.3. Реализация процедурных абстракций

Реализация ПА должна выполнять все действия, определенные в спецификации. Каждый язык программирования имеет свой механизм и особенности реализации ПА. Например, в Паскале в процедурах существует возможность чтения и модификации глобальных переменных; она не должна использоваться при реализации любых абстракций – значение абстракции при этом зависит от контекста, в котором она находится, т.е. снижается уровень абстракции.

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

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

Замечания по реализации процедурных абстракций.

1. При реализации ПА могут быть оставлены неопределенными некоторые выполняемые процедурой функции. Такая процедура называется недоопределенной – для некоторых значений входных параметров на выходе вместо единственного правильного результата имеется набор допустимых результатов. Реализация может ограничивать этот набор одним значением, однако он может быть любым из числа допустимых. Например, процедура Search будет недоопределенной, если не будет указано точно, какой индекс должен быть возвращен, если искомое значение встречается в массиве несколько раз.

В спецификации должны быть оговорены все существенные для пользователя подробности, все остальные могут оставаться неопределенными.

2. Процедура должна обладать хорошо определенным и легко объяснимым назначением, независимым от контекста ее использования.

3. Частичная или общая абстракция? Общие процедуры (не имеют ограничений на входные параметры) являются более безопасными, чем частичные, так как неудовлетворение входных требований в частичной процедуре может привести к неверной работе программы. В свою очередь, частичные процедуры чаще более эффективны в реализации, чем общие. Критерии выбора между частичной и общей абстракцией: 1) эффективность; 2) корректное выполнение с меньшим числом потенциальных ошибок.

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

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

3.2.4. Более обобщенные (параметризованные) процедуры

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

Спецификация параметризованной процедуры в заголовке содержит указание на параметр-тип. Предложение requires помимо прочих ограничений содержит ограничения, накладываемые на параметры-типы.

Например, абстракция Search требует, чтобы ее параметр t имел операции equal (равно) и less (меньше), упорядочивающие t.

Search=proc[t:type](a: array[t],x:t) returns(i: int)


requires
t имеет операции: equal, less: proctype(t,t) returns(boolean);
t
упорядочивается через less, и массив a упорядочен по возрастанию через less.

effects Если элемент x принадлежит массиву a, то возвращается значение i такое, что a[i]=x; в противном случае – значение i на единицу больше, чем значение верхней границы массива a.

Параметризованная абстракция представляет собой класс взаимосвязанных абстракций, определенных в одной спецификации. Спецификация процедуры получается из спецификации класса путем замены имени параметра-типа его значением и удалением из предложения requires ограничений на тип параметров. Если язык программирования имеет в наличии средства реализации параметризованных абстракций, то класс процедур реализуется в виде одной программы. Если язык реализации не имеет средств для создания параметризованных абстракций, то класс абстракций реализуется в виде нескольких непараметризованных процедур для всех допустимых типов параметров.

3.3. Абстракция данных

3.3.1. Понятие абстракции данных

Процедурные абстракции дают нам возможность добавлять в базовый язык новые операции. Необходимость добавления в базовый язык новых типов данных удовлетворяется абстракцией данных.

Область применения программы определяет набор новых типов данных. Например, при создании компилятора или интерпретатора полезны стеки и символьные таблицы, в аналитических вычислениях – полиномы, в матричной алгебре – векторы и матрицы. Новые типы данных должны включать в себя абстракцию через параметризацию и абстракцию через спецификацию. Смысл АП – использование параметров, АС – включение операций над типом в сам тип: абстракция данных = данные + операции.

3.3.2. Спецификация абстракции данных

Состоит из заголовка, определяющего имя типа и имена его операций, и двух секций – описания и операций:

Dname=data type is список операций

Описание – описание абстракции данных

Операции – спецификации всех операций над типом

end Dname

В секции описания также должно быть указано, изменяемый или неизменяемый это тип (операции изменяемого типа могут модифицировать тип).

Пример. Спецификация очереди целых чисел.

TQueue=data type is Create, Empty, Insert, Remove, Destroy

Описание

Тип данных TQueue используется для хранения целых значений. Элементы включаются в очередь и исключаются из очереди только по принципу «первым пришел – первым обслужен». Тип изменяемый.

Операции

Create = proc() returns(TQueue)

effects Возвращает новую очередь без элементов в ней.

Empty = proc(q: TQueue) returns(bool)

effects Возвращает значение true, если в очереди q нет
элементов, и значение false в противном случае.

Insert = proc(q: TQueue; NewValue: int)

modifies q

effects Добавляет элемент со значением NewValue в конец
очереди q.

Remove = proc(q:TQueue) returns(int)

requires Очередь q не пуста.

modifies q

effects Возвращает элемент из начала очереди q и удаляет этот элемент из очереди.

Destroy = proc(q:TQueue)

modifies q

effects Удаляет из памяти очередь q.

end TQueue

3.3.3. Реализация абстракции данных

Для реализации типа данных мы выбираем представление для объектов и реализуем операции в терминах этого представления. Например, возможные представления для типа TQueue – массив целых чисел и последовательность динамических элементов. Таким образом, при реализации абстракции данных мы можем говорить о двух разных типах: о новом типе TQueue, который мы реализуем (абстрактный тип), и, например, о последовательности динамических элементов, которая используется для представления (тип представления). Тип представления может быть изменен, если понадобится изменить свойства реализации процедурной абстракции (повысить скорость обращения к данным типа или экономнее использовать память). При этом спецификация абстрактного типа данных не изменится.

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

Обсуждение реализации абстракции данных.

1. Изменяемость. Абстракции данных могут быть либо изменяемыми (списки, массивы), либо неизменяемыми (числа, полиномы). Это свойство типа, а не его реализации. Реализация же должна поддерживать это свойство абстракции. Неизменяемые абстракции более надежны, однако для них чаще используются операции создания новых и уничтожения ненужных объектов.

2. Классы операций:

а) примитивные конструкторы – создают объекты соответствующего типа, не используя никаких объектов в качестве аргументов (операция Create очереди);

б) конструкторы – используют в качестве аргументов объекты соответствующего им типа и создают другие объекты того же типа, например операция копирования очереди:

Copy = proc(q: TQueue) returns(TQueue)

effects Возвращает копию очереди q.

в) модификаторы – модифицируют объекты соответствующего им типа (операции Insert, Remove для очереди); только изменяемые типы могут иметь модификаторы;

г) наблюдатели используются для получения информации об объекте; в качестве аргумента они используют объект соответствующего им типа, а возвращают аргумент другого типа, например операции Empty или Size для очереди.

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

3.4. Исключительные ситуации (ИсС)

3.4.1. Общие положения

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

Оповещение подпрограммы о возникшей проблеме.

1. Определение специфического результата, возвращаемого в случае ошибки, например

Fact =proc(n: int) returns (int)

effects Если n>0, то возвращает n!, иначе возвращает 0.

Не очень хорошее решение, так как может не быть значения, с помощью которого можно было бы оповестить об ошибке.

2. Обобщение процедуры. Область определения D делится на несколько подмножеств, объединение которых дает D: D=D0 È D1 È ... È Dn. В каждом из подмножеств процедура ведет себя по-разному. Назовем подмножество D0 «обычным» (это допустимое подмножество области определения). Остальные подмножества могут получать любые имена (по усмотрению программиста), но все они относятся к исключительным ситуациям и в этих случаях должно обеспечиваться оповещение пользователя. Таким образом, процедура определена на следующем наборе данных:

pD0 ® обычный (R0)

D1 ® имя1 (R1)

…                                  исключительные ситуации

Dn ® имяn (Rn)

где имя1, ..., имяn – имена ИсС, соответствующих аргументам, принадлежащим D1, ..., Dn; R1, ..., Rn – описание возвращаемых результатов в каждой ИсС (может быть пустым).

3.4.2. Спецификации процедур, вызывающих исключительные ситуации

За предложением returns в заголовок процедуры добавляется предложение: signals список имен и результатов ИсС. Например

Search =proc(a: array[real], x: real) returns(ind: int) signals (duplicate(ind1:int), not_in)

Это предложение говорит о том, что процедура Search может вызывать две ИсС: duplicate (результат – целое число) и not_in (без результата). Имя ind1 вводится для ссылок на дополнительный результат в остальной части спецификации. Как и раньше секция effects должна определять поведение процедуры для всех фактических аргументов, отвечающих предложению requires. Это поведение включает в себя и ИсС (что приводит к их вызову, и как реагирует процедура).

Спецификация процедуры Search:

Search =proc(a: array[real], x: real) returns(ind: int)
signals (duplicate(ind1:int), not_in)

requires массив a упорядочен по возрастанию

effects Если xÎa один раз, то возвратить ind, такой, что a[ind]=x. Если xÎa более чем 1 раз, то сигнализировать об исключительной ситуации duplicate (ind1), где ind1 – индекс для одного из x. Иначе сигнализировать об исключительной ситуации not_in.

Заметим, что в секции effects предполагается, что все требования предложения requires удовлетворены.

Область определения процедуры Search:

D0={<a, x>|xÎa ровно один раз};

D1={<a, x>|xÎa более чем один раз};

D2={<a, x>|xÏa};

Здесь <a, x> – пара, состоящая из массива и вещественного числа.

Существует еще одна ИсС, кроме перечисленных в строке signals. Она имеет имя failure и один аргумент – строку (failure – неудача, неуспех). Каждая ИсС, возникшая в вызванной процедуре и не обрабатывающаяся явно в вызывающей процедуре, автоматически преобразуется в ситуацию failure. В процедуре Search failure(s) – ситуация, при которой входной аргумент a не отсортирован, либо программная или системная ошибка, s – имя ИсС и информация для программиста.

3.4.3. Использование исключительных ситуаций в программах

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

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


2. Маскирование ИсС вызывающей подпрограммой – полная обработка исключительной ситуации.

ИсС следует использовать для устранения большинства ограничений предложения requires. Эти ограничения следует оставлять только из соображений эффективности (с внесением риска) или если контекст использования ограничен (ограничения удовлетворяются). Например, в процедуре Search, возможно, стоит затратить некоторые усилия и выявить ИсС «массив не отсортирован», чтобы затем сигнализировать об исключительной ситуации процедуре failure.

При реализации процедуры программист должен гарантировать, что она во всех ситуациях завершится в соответствии со спецификацией.