Обмен с внешней средой (ввод-вывод) обслуживается в Аде предопределенными библиотечными пакетами. Имеются средства об­мена значениями не только предопределенных типов (как в Паска­ле), но и типов, определяемых программистом.

Наконец, имеются средства статической параметризации модулей (действующие до начала исполнения программы, в период компиля­ции) - аппарат РОДОВЫХ модулей. Параметры таких модулей (ро­довые параметры) в отличие от динамических параметров подпрог­рамм и процедур могут быть не только объектами данных некоторо­го типа, но и такими объектами, как типы и подпрограммы (которые в Аде не считаются объектами данных). Так что общие модули, рас­считанные на применение ко всем типам данных определенной кате­гории, в Аде следует оформлять как родовые.

На этом закончим краткий обзор языка.

2.4. Пошаговая детализация средствами Ады

Рассмотрим следующую задачу.

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

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

НЕ нашли? Не то? Что вы ищете?

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

Первый шаг детализации. Уточним постановку задачи в терми­нах языка Ада. Так как речь идет не об алгоритме, а о предоставле­нии пользователю комплекса услуг, в Ада-терминах естественно ото­бразить этот комплекс на совокупность "логически связанных" объ­ектов, в данном случае - связанных по меньшей мере совместным использованием. Другими словами, первое наше решение - создавать ПАКЕТ, а не подпрограмму или задачу. Вспоминая, что разделение спецификации и тела пакета позволит скрыть от пользователей па­кета детали реализации (в частности, представление сети, в полном соответствии с требованиями), получаем еще одно подтверждение, что решение правильное.

Итак, создаем ПАКЕТ. Нужно придумать ему название, выража­ющее назначение предоставляемого комплекса услуг. Попробуем "сеть". Нехорошо. По-видимому, так лучше называть тот объект, который будет моделироваться, и чье представление нужно скрыть в теле нашего пакета. Попробуем "моделирование сети связи". Луч­ше, но слишком конкретно. Хотя в постановке задачи и требованиях речь идет именно о моделировании сети связи, однако специфика связи (кроме самой сети) ни в чем не отражена (нет и речи о пропу­скной способности каналов, классификации сообщений и т. п.), да и специфика моделирования не затронута (никаких моделей отправи­телей, получателей и т. п.). Скорее мы собираемся предоставить лишь комплекс услуг по управлению сетью. Так и назовем пакет:

"управление_сетью".

Точное название настраивает на то, чтобы в пакете не было лишнего, а пользова­телю помогает применять наш комплекс и в других областях.

Второй шаг детализации. Теперь нужно написать спецификацию пакета, объявив все объекты, с которыми сможет работать пользова­тель:

0.  with параметры_сети; use параметры_сети;

1.  package управление_сетью is

2. type узел is new INTEGER range 1..макс_узлов;

3.  type число_связей is new INTEGER range 0..макс_связей;

4.  type индекс_узла is new INTEGER range 1..макс_связей;

5.  type перечень_связей is array (индекс_узла) of узел;

6.  type связи is

7. record

8.  число : число_связей := 0;

9.  узлы : перечень_связей;

10. end record ;

11.-- операции над сетью

12.  procedure вставить (X : in узел);

13.  procedure удалить (X : in узел);

14.  procedure связать (X, Y : in узел);

15.-- сведения о текущем состоянии сети

16.  function узел_есть (X : узел) return boolean;

17.  function все_связи (X : узел) return связи;

18. end управление_сетью;

Текст спецификации пакета с названием "управление_сетью" при первоначальном знакомстве может показаться непонятным. Во всяком случае не верится, что он получен одним шагом детализа­ции. Действительно, шаг зависит как от привычки проектировщика, так и от свойств языка. Ведь в общем случае далеко не каждый мел­кий шаг поддерживается подходящим законченным языковым конст­руктом. Например, в Аде шаги нельзя дробить сколь угодно мелко хотя бы потому, что действует правило последовательного определения: при очередном определении можно использовать только предопределенные, внешние или ранее объявленные имена.

Но при пошаговой детализации нельзя заранее объявить те име­на, которые понадобятся - они попросту неизвестны. Когда проекти­руют совокупность модулей, это не помеха (порядок модулей несу­ществен). А вот внутри модулей правило последовательного определения мешает пошаговой детализации [особенно внутри пакетов; по­чему?]. Приходится либо применять средства, выходящие за рамки Ады (например, псевдокод), либо записывать пакет "с конца к нача­лу" - этот порядок с учетом правила последовательного определения лучше отражает последовательность появления имен при пошаговой детализации.

С точки зрения принципа технологичности. любые несоответствия языка потребно­стям пошаговой детализации служат источником "точек роста", намечают направле­ние развития либо самого языка, либо других связанных с ним технологических инст­рументов. Для Ады, в частности, разрабатываются специальные средства поддержки пошагового конструирования программ.

Упражнение. Укажите внешний эффект (исходные данные и результаты) хотя бы одного из таких средств.

Подсказка. Редактор, располагающий фрагменты Ада-программы в порядке, соот­ветствующем правилу последовательного определения.

Упражнение (повышенной сложности). Разработайте проект хотя бы одного та­кого средства; проект комплекса таких средств.

Итак, проявим более мелкие шаги проектирования нашего паке­та.

Шаг 2.1 (строка 17). Объявляем функцию с названием "все_связи", формальным параметром с названием "X" (значениям этого па­раметра приписан тип с названием "узел") и результатом, которому приписан тип с названием "связи".

Ниже будем писать короче: функцию "все_связи" с параметром "X" типа "узел" и результатом типа "связи.

Эта функция дает возможность узнавать о текущем состоянии се­ти (точнее, о связях одного узла). Обратите внимание, пока совер­шенно неясно, что такое "узел" и "связи". Это лишь названия, от­ражающие роль в создаваемом комплексе услуг тех объектов, кото­рые еще предстоит воплотить в программе.

Шаг 2.2 (строка 16). Нехорошо запрашивать связи узла, не зная, имеется ли он в сети. Поэтому (продолжая предоставлять средства узнавать о состоянии сети) объявляем функцию узел_есть с пара­метром "X" типа узел и результатом логического типа (BOOLEAN).

Замечание. Обратите внимание, мы записываем только формальные СПЕЦИФИ­КАЦИИ (заголовки) функций. Содержащихся в них сведений достаточно, чтобы можно было (столь же формально) написать вызов такой функции. Но, во-первых, рано или поздно придется написать ТЕЛО функции (сделаем это в ТЕЛЕ пакета). Во-вторых, нужно как-то сообщить пользователю, что же делает объявляемая функ­ция.

Например, из объявления в строке 16 пользователь поймет, что, задав функции узел_есть аргумент типа узел, он получит в качестве результата истину или ложь. Не откуда ему узнать, что истина соответствует случаю, когда узел с указанным именем есть в сети, а ложь - когда его нет. Название функции лишь намекает на такое истол­кование. Конечно, названия должны быть мнемоничными и помогать запоминать смысл программных объектов, но они не могут заменить точных сведений.

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

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

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

По выделимости Ада превосходит, например, Алгол-60 или Бейсик, так как по­зволяет адекватно оформлять не только компоненты-функции, но и компоненты-дан­ные, и компоненты-задачи, и компоненты более "тонкого" назначения. Другими сло­вами, Ада выигрывает в выделимости потому, что предоставляет более развитые сред­ства абстракции и конкретизации.

Упражнение. При чем здесь абстракция-конкретизация?

Шаг 2.3 (строки 12-14). Предоставляя средства для изменения се­ти, определяем три процедуры: вставить, удалить и связать (пара­метры у них типа узел).

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24