Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP / books / Osnovi objektno-orientirovannogo programmirovaniya.pdf
Скачиваний:
63
Добавлен:
03.03.2016
Размер:
9.04 Mб
Скачать

Использование утверждений

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

*Помощь в создании корректного ПО.

*Поддержка документирования.

*Поддержка тестирования, отладки и гарантия качества.

*Поддержка приемлемого способа обработки неисправностей.

Только два последних пункта предполагают мониторинг утверждений в период выполнения.

Утверждения как средство для написания корректного ПО

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

Ключевая идея этой лекции - Проектирование по контракту. Использование компонент некоторого модуля является контрактом с его службами. Хорошие контракты точно специфицируют и ограничивают права и обязанности каждого участника. В проектировании ПО, где корректность и устойчивость так важны, необходимо раскрытие терминов контракта, как предварительное условие их следованию. Утверждения дают способ точно установить, что ожидается и что гарантируется каждой стороне в этом соглашении.

Использование утверждений для документирования: краткая форма класса

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

|В самом последнем разделе этой лекции можно ознакомиться с проектом, где эти правила были проигнорированы, что обошлось в $500 миллионов и привело к провалу космического проекта. |

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

информацию, которая полезна авторам клиентских классов, ничего не показывая из скрытых компонент, и не раскрывая реализации открытых. Но краткая форма сохраняет утверждения, составляющие основу документации, устанавливая контракты, которые класс предлагает своим клиентам.

Вот пример краткой формы класса STACK4:

indexing

description: "Стеки: Структуры с политикой доступа Last-In, First-Out % %Первый пришел - Последний ушел, с фиксированной емкостью"

class interface STACK4 [G] creation make

feature -- Initialization (Инициализация) make (n: INTEGER) is

--Создать стек, содержащий максимум n элементов require

non_negative_capacity: n >= 0 ensure

capacity_set: capacity = n end

feature -- Access (Доступ) capacity: INTEGER

--Максимальное число элементов стека

count: INTEGER

--Число элементов стека item: G is

--Элемент в вершине стека require

not_empty: not empty -- i.e. count > 0 end

feature -- Status report (Отчет о статусе) empty: BOOLEAN is

--Пуст ли стек?

ensure

empty_definition: Result = (count = 0) end

full: BOOLEAN is

--Заполнен ли стек? ensure

full_definition: Result = (count = capacity) end

feature -- Element change (Изменение элементов) put (x: G) is

--Втолкнуть x в вершину стека

require

not_full: not full ensure

not_empty: not empty added_to_top: item = x

one_more_item: count = old count + 1 end

remove is

-- Удалить элемент вершины стека require

not_empty: not empty -- i.e. count > 0 ensure

not_full: not full

one_fewer: count = old count - 1 end

invariant

count_non_negative: 0 <= count count_bounded: count <= capacity empty_if_no_elements: empty = (count = 0) end

Эта краткая форма не является синтаксически правильным текстом класса, посему здесь используется термин class interface вместо обычного термина class. Хотя достаточно просто превратить эту форму в правильный отложенный класс, известное понятие, рассматриваемое в деталях при изучении наследования.

|В среде ISE получить краткую форму можно одним щелчком соответствующей кнопки в Class Tool; можно генерировать либо плоский текст, либо текст в форматах HTML, RTF, MML (FrameMaker), TEX и других. Можно определить и свой собственный формат. |

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

Краткая форма документации особенно интересна по следующим причинам:

*Документация является более высокой формой абстракции, чем объект, который она описывает. Это основное требование, предъявляемое к качественной документации. Фактическая реализация, описывающая "как", удаляется. Утверждения, объясняющие "что", а в некоторых случаях и "почему", остаются. Сохраняются заголовочные комментарии к программам и описания, включаемые в предложение indexing, дополняющие в менее формальной форме утверждения, поясняя цель и назначение программы.

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

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

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

*Здесь нет утверждений, так что вся спецификация сводится к объявлению типов и комментариям.

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

Краткая форма, дополненная ее вариантом - плоско-краткой формой ( flat-short form ), изучаемой при рассмотрении наследования, является принципиальным вкладом в ОО-метод. В повседневной практике ОО-разработки она появляется не только как средство

документирования, но и как стандартный формат, в котором разработчики и менеджеры изучают существующие проекты, разрабатывают новые и обсуждают предложения по изменению проектов.

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

Мониторинг утверждений в период выполнения

Пришло время, дать полный ответ на вопрос: "какой эффект производят утверждения в период выполнения?". Как отмечалось, ответ определяется разработчиком, имеющим возможность управлять параметрами компиляции. Выбор нужных параметров не требует изменения текста класса, вместо этого меняется содержимое Ace файла. Напомню, Ace файл написан на языке Lace, описывающем компиляцию и сборку системы.

|Напомню также, что Lace один из возможных языков, позволяющих управлять сборкой системы; он не является неизменяемым компонентом метода. Но всегда необходимо подобное средство для перехода от отдельных компонент к полной компилируемой системе. |

Вот пример применения Ace файла, устанавливающего некоторые параметры мониторинга утверждений:

system painting root GRAPHICS

default

assertion (require) cluster

base_library: "\library\base" graphical_library: "\library\graphics" option

assertion (all): BUTTON, color_BITMAP end

painting_application: "\user\application" option

assertion (no) end

end -- system painting

Предложение default указывает, что для большинства классов системы проверяться будут только предусловия ( require ). Два кластера переопределяют установки умолчания. Кластер graphical_library будет наблюдать за всеми ( all ) утверждениями в классах BUTTON и color_BITMAP. Кластер painting_application вообще отменяет наблюдение за утверждениями во всех его классах. Этот пример иллюстрирует возможности мониторинга на разных уровнях - всей системы, отдельных кластеров, отдельных классов.

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

*no - не выполнять никакое из утверждений. В этом режиме оказывают на выполнение не больший эффект, чем комментарии;

*require - только проверка выполнимости предусловий на входе программ;

Соседние файлы в папке books