Подчеркнем, что в теле определяющего пакета объекты приват­ных типов ничем не отличаются от любых других - их строение из­вестно, выборка и индексация разрешены!

4.3.3. Строго регламентированный доступ. Ограниченные приват­ные типы

В общем случае к объектам приватных типов применимы также операции присваивания и сравнения на равенство и неравенство (полных объектов, как в процедуре две_сети!). Хотя это и удобно (такие операции часто нужны и неразумно заставлять программи­стов определять их для каждого приватного типа), все-таки концеп­ция строго регламентированного доступа в таких типах не выдержа­на до конца. В Аде она точно воплощена лишь в так называемых ОГРАНИЧЕННЫХ приватных типах. К объектам таких типов не­применимы никакие предопределенные операции, в том числе присваивания и сравнения - все нужно явно определять (в определяю­щем пакете). Объявления ограниченных приватных типов выделя­ются ключевыми словами limited private, например:

type ключ is limited private;

Применение к объектам типа "ключ" операций присваивания или сравнения вызовет сообщение об ошибке, если только в определяю­щем пакете для этого типа не определены свои собственные опера­ции, обозначаемые через ":=", "=" или "/=".

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

Присваивания. Мы уже упоминали, что бывают ЯП вовсе без присваивания. Таковы чистый Лисп, Базисный Рефал, функцио­нальные и реляционные языки. Подробнее поговорим о них позже. Чтобы соответствовать роли базового языка, Ада должна предостав­лять средства развития, позволяющие моделировать и такие ЯП, причем моделировать в точности, с гарантией защиты создаваемых абстракций. Так что ограниченные приватные типы вместе со сред­ством их определения (пакетом) - важнейшее средство развития в современном базовом ЯП.

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

Упражнение (повышенной сложности). Создайте определяющий пакет для каж­дой из рассмотренных далее моделей ЯП.

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

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

Вопрос. Что можно сказать в этих условиях об исходных данных и результатах?

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

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

Поэтому в Аде задачные типы - ограниченные приватные по оп­ределению и, следовательно, всякая попытка сравнить задачи на ра­венство квалифицируется как ошибка. Кстати, любые составные ти­пы с компонентами ограниченного типа считаются ограниченными.

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

4.3.4. Инкапсуляция

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

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

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

4.4. Характеристики, связанные с типом. Класс значений, базовый набор операций

Продолжим анализ общей концепции типа данных. До сих пор мы концентрировали внимание только на способе привязки характе­ристик к объектам данных. Сутью характеристик мы при этом не интересовались. Перед нами очередной пример разумной абстрак­ции. Абстракция от сути характеристик привела к концепции уни­кальности типа. Концепция уникальности - к простоте прогнозиро­вания-контроля. А простота прогнозирования-контроля позволяет по-новому взглянуть на саму концепцию типа.

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

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

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

Может показаться, что нетрудно проделать и обратное - указать для каждого типа все применимые операции. Но представим себе, что пакет управление_сетями предоставлен в распоряжение большо­го коллектива пользователей. Каждый из них волен написать сег­менты, использующие этот пакет, и в этих сегментах ввести свои операции над объектами типа "сети". Например, один ввел процеду­ру выделения связных подсетей, другой - процедуру подсчета хрома­тического числа сети, третий - вычисления минимального маршрута между двумя узлами. Следует ли считать характеристикой типа "се­ти" набор из всех этих операций? И каков содержательный смысл в такой характеристике? Ведь в разных контекстах доступны разные элементы этого набора.

Лучше считать характеристикой типа относительно постоянное его свойство, связанное с ним в любых контекстах. Таковы КЛАСС ЗНАЧЕНИЙ объектов этого типа и БАЗОВЫЙ НАБОР ОПЕРА­ЦИЙ, применимых к этим объектам. В Аде эти две характеристики связываются с типом соответственно ОБЪЯВЛЕНИЕМ ТИПА и ОП­РЕДЕЛЯЮЩИМ ПАКЕТОМ.

4.5. Воплощение концепции уникальности типа. Определение и ис­пользование типа в Аде (начало)

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

4.5.1. Объявление типа. Конструктор типа. Определяющий пакет

Объявление типа вводит имя нового типа и связывает это имя с конструктором типа. Последний служит для создания нового типа из уже известных и располагается в объявлениях типов после ключево­го слова is.

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

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

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