
- •1. Характеристики и признаки больших программных продуктов и систем
- •2. Жизненный цикл программного обеспечения (класс крупных продуктов, систем)
- •Модели жизненного цикла по Каскадная модель
- •Спиральная модель
- •Итерационная модель
- •Стандарт жизненного цикла по гост 34.601-90
- •3. Проблемы и риски программных проектов. Средства борьбы со сложностью
- •Задачи управления рисками
- •4. Анализ требований к программному обеспечению, особенности проектирования крупных пс
- •5. Планирование разработки и распределение работ, организация коллективной разработки пс
- •6. Спецификации. Моделирования. Верификация методом проверки понятности
- •7. Факторы надежности разработки в языках программирования, в частности Ада
- •8. Компонентно-ориентированное проектирование и программирование. Пример - модули компиляции и внутренняя структура Ада программ
- •9. Согласованность средств проблемной ориентации в проектных решениях и при разработке на языке программирования
- •10. Гибкость программных конструкций на примере языка Ада
- •11. Забезпечення динамічності структур даних на прикладі мови Ада
- •Процессы жц верификация и валидация программ
- •Функциональное тестирование
- •12. Проектування обробки виключень на прикладі мови Ада. Исключения
- •Упрощение управляющей структуры
- •Возбуждение и обработка исключений
- •Іі. Засоби контролю та управління якістю
- •Управління якістю у розробці великих пс: система видів якості. Вариант №1
- •Глобальное управление качеством (tqm, Total Quality Management)
- •Принципы управления, принципы tqm
- •Процессная модель управления качеством
- •Внутрішня та зовнішня якості пз: характеристики та підхарактеристики
- •Система методів перевірки функціональної вірності програм
- •7.1. Процессы жц верификация и валидация программ
- •Система мір внутрішньої та зовнішнього якості пз, опис мір (метрик)
- •21(9) Підхарактеристика якості продукції «узгодженість функціональності»
- •23(11) Контроль якості в управлінні розробкою пс
Возбуждение и обработка исключений
Чтобы возбудить исключительную ситуацию, а не обрабатывать ошибки на месте, можно переписать текст следующим образом:
action1;
if error1 then raise exc1; end;
action2;
if error2 then raise exc2; end;
action3;
if error3 then raise exc3; end;
...
При выполнении команды raise exc нормальный порядок вычислений прерывается, и управление передается обработчику исключений (exception handler), представленному специальным блоком подпрограммы и имеющему вид:
exception
when exc1, ...=> treatment1;
when exc2 ...=> treatment2;
...
При возбуждении исключения exc первым его обрабатывает захвативший его обработчик из динамической цепи вызовов - списка элементов, начинающегося подпрограммой, содержащей вызвавшее исключение предложение raise, и всеми вызывающими подпрограммами, как показано на рис. 2:
Рис.
2.
Цепь вызовов
Говорят, что обработчик захватывает exc, если exc появляется в одном из его предложений when (или он содержит предложение вида when others). Такой обработчик выполняет соответствующие команды (после символа =>), после чего управление передается вызывающей программе или заканчивается в случае главной программы. (Ada имеет понятие главной программы.) Если никакой обработчик в динамической цепи не обрабатывает exc, выполнение приложения заканчивается, и управление возвращается к операционной системе, а она, вероятно, выведет системное сообщение об ошибке.
Стоит повторить основное правило:
Правило исключений языка Ada Выполнение любого обработчика исключений языка Ada должно заканчиваться либо выполнением команды raise, либо повтором охватывающей подпрограммы. |
Исключения в Ada - это управляющие структуры, предназначенные для отделения обнаружения аварийных ситуаций от их обработки и сохранения простоты структуры ПО. Однако на практике этого часто не происходит.
Запись raise some_exception дает впечатление освобождения от запутанной и скучной задачи слежения за необычными ситуациями, позволяя сосредоточиться на самом алгоритме, имеющем дело с нормальной ситуацией. Но вызов исключения еще не решает задачи. Исключения в пакете STACKS типичны. Попытка поместить элемент в полный стек вызывает ошибку Overflow, а попытка доступа к пустому стеку вызывает Underflow. Как обрабатывать Underflow, ошибку, возникающую при вызове remove или item на пустом стеке? Обсуждение Проектирования по Контракту показало, что эти подпрограммы не могут знать, что следует делать в такой ситуации. Вся ответственность лежит на клиенте, вызвавшем эти подпрограммы, только он может решить, что следует делать. У него и должен содержаться код вида:
[2]
use REAL_STACKS;
procedure proc (...) is
s: STACK; ...
begin
... remove (s); ...
exception
when Underflow => action1;
...
end proc;
Клиент должен точно определить, что происходит в случае ошибки. Опустить оператор when Underflow было бы ошибкой проекта. Сравните это с обычной, не основанной на исключении, формой вызова:
[3]
if not s.empty then s.remove else action1 end
(или вариантом, определяющим ошибку апостериори). Форма [2], использующая исключения, отличается от формы [3] только двумя аспектами:
код для обработки ошибки action1 текстуально отделен от вызова, приведшего к ошибке;
обработка ошибки одинакова для всех подобных вызовов.
Хотя и желательно избегать глубоко вложенных структур обработки ошибок if... then... else..., приведенных в начале лекции, то место в алгоритме, где обнаруживается ошибка, часто предоставляет наилучшую информацию для ее обработки. Если разделить обнаружение и обработку, то могут потребоваться сложные управляющие структуры для случаев, требующих повторного запуска или продолжения обработки.
Кроме того, для подпрограммы, содержащей несколько вызовов remove, способ работы с пустыми стеками вряд ли будет одним и тем же в каждом случае.
Существуют два общих стиля использования исключений. Стиль управляющей структуры рассматривает исключения как нормальный механизм для обработки всех случаев, отличающихся от обычных. Стиль аварийных случаев рассматривает их как непредсказуемые ситуации, когда все другие механизмы не работают. Объектный подход rescue/retry, описанный ранее, тяготеет к стилю аварийных случаев, хотя может использоваться и для первого стиля. Обработка исключений в языке Ada больше ориентирована на стиль управляющей структуры.
Каждый должен решить, какой стиль ему больше нравится. Но в любом случае, следует помнить, что не нужно наивно возлагать надежды на использование исключений. Есть механизм исключений или его нет, ошибки при выполнении программы - это факт жизни системы, и она должна их явно обрабатывать. Хороший методологический подход, поддерживаемый эффективным механизмом исключений, может быть полезным. Но проблеме обработки ошибок присуща природная сложность, и никакая волшебная палочка от нее не избавит.