Опубликован: 17.10.2005 | Доступ: свободный | Студентов: 8823 / 588 | Оценка: 4.38 / 4.10 | Длительность: 41:16:00
ISBN: 978-5-7502-0255-3
Специальности: Программист
Лекция 8:

Динамические структуры: объекты

Составные объекты и развернутые типы

Обсуждение структуры объектов времени выполнения показало важную роль ссылок. Для завершения картины необходимо выяснить, как работать со значениями, представляющими собой не ссылки на объекты, а непосредственно сами объекты.

Ссылок не достаточно

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

  • В предыдущей лекции была поставлена важная цель - построение полностью унифицированной системы типов. В этой схеме базовые типы (BOOLEAN, INTEGER и др.) обрабатываются аналогично типам, введенным разработчиком (POINT, BOOK и др.). Тем не менее, если используется сущность n типа INTEGER, то в большинстве случаев удобнее полагать, что значение n - целое число, а не ссылка на объект содержащий целое число. Это удобнее отчасти по соображениям эффективности. Понятно, что для размещения целочисленных объектов необходимо больше памяти, а на обработку косвенного доступа к ним - дополнительное время. Кроме того, концептуально целое число и ссылка на целое число - совершенно различные понятия. Этот довод важен, если нашей целью является построение точной модели.
  • Даже в случае сложных, определенных программистом объектов, может оказаться предпочтительным включение в объект O1 подобъекта O2, а не ссылки на внешний объект O2. Причиной такого подхода могут быть повышение эффективности, точное моделирование или и то, и другое.

Развернутые типы

Удовлетворить потребность в составных объектах очень просто. Пусть C - класс, определенный так, как это делалось до сих пор

class C feature
   ...
end

Класс C может использоваться в качестве типа. Любая сущность типа C является ссылкой. По этой причине C называется ссылочным типом (reference type).

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

x : expanded C

Эта нотация использует новое ключевое слово expanded (развернутый). Нотация expanded C означает, что экземпляры этого типа в точности соответствуют экземплярам C. Единственное отличие от обычного объявления типа состоит в том, что сущности типа C обозначают ссылки, которые могут быть присоединены к экземплярам C, а сущности типа expanded C обозначают непосредственно экземпляры C.

Таким образом, к структуре, определенной в предыдущих разделах, добавлено понятие составного объекта (composite object). Объект O называется составным, если одно или более его полей являются объектами - подобъектами (subobjects) O . Следующий класс является примером описания составных объектов:

class COMPOSITE feature
   ref: C
   sub: expanded C
end

Класс COMPOSITE имеет два атрибута: ref, обозначающий ссылку, и sub, обозначающий подобъект. Вот как выглядит прямой экземпляр COMPOSITE.

Составной объект с одним подобъектом

Рис. 8.19. Составной объект с одним подобъектом

Поле ref является ссылкой, присоединенной к экземпляру C (возможно, пустой ссылкой). Поле sub содержит экземпляр C и не может быть пустым.

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

expanded class E feature
   ... Далее все аналогично любому другому классу ...
end

Так определенный класс называется развернутым классом. Такое объявление класса никак не отражается на экземплярах класса, они остаются такими же, как если бы класс был объявлен просто class E. Но сущности типа E изменяются - теперь их значения не ссылки, а сами объекты. Как следствие этой новой возможности понятие развернутого типа включает два случая:

Определение: развернутый тип

Тип является развернутым в двух случаях:

Он задан в форме: expanded C

Он задан в форме E, где E - развернутый класс.

Объявление вида

x: expanded E

где E - развернутый класс, не будет ошибкой, поскольку эквивалентно

x: E

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

Роль развернутых типов

Почему нам нужны развернутые типы? Они играют три важные роли:

  • улучшают эффективность;
  • обеспечивают лучшее моделирование;
  • поддерживают базисные типы в унифицированной ОО-системе типов.

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

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

Рассмотрим два объявления атрибутов:

D1. ref: S
D2. exp: expanded S

Объявления появляются в классе C, предполагается также, что S это ссылочный класс. Объявление D1 отражает тот факт, что каждый экземпляр класса C "знает о" существовании некоторого экземпляра S (если только ref не является void ). Объявление D2 более требовательное: оно устанавливает тот факт, что каждый экземпляр класса C "содержит" экземпляр S. Даже если не думать о проблемах реализации, следует понимать, что речь идет о двух разных отношениях.

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

Вот пример объявления класса:

class WORKSTATION feature
   k: expanded KEYBOARD
   c: expanded CPU
   m: expanded MONITOR
   n: NETWORK
   ...
end

Рабочая станция имеет клавиатуру, ЦПУ, монитор и подключена к сети. Клавиатура, ЦПУ и монитор являются частью данного компьютера и не могут разделяться двумя или несколькими рабочими станциями. Однако несколько рабочих станций подключены к одной и той же сети. Эти особенности проявляются в определении класса, использующем развернутые типы для первых трех атрибутов и ссылочный тип для атрибута "сеть".

Отношения между объектами: "знает о" и "содержит"

Рис. 8.20. Отношения между объектами: "знает о" и "содержит"

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

Третье важное приложение развернутых типов фактически является частным случаем второго. В предыдущей лекции подчеркивалась желательность унифицированной системы типов, включающей как встроенные, так и пользовательские типы. Пример REAL использовался, чтобы показать, как с помощью инфиксных и префиксных компонентов можно промоделировать понятие вещественного числа как класса. То же самое нетрудно проделать и для других базисных типов: BOOLEAN, CHARACTER, INTEGER, DOUBLE. Но проблема все же остается. Если классы рассматривать как ссылочные, то сущности базисных типов, такие как

r: REAL

будут в период выполнения ссылками на возможные объекты, содержащие значение (в данном случае REAL ). Это неприемлемо: чтобы соответствовать общей практике программирования значение должно быть не ссылкой, а самим вещественным числом. Решение проблемы немедленно следует из обсуждения - класс REAL следует объявить как развернутый. Его объявление должно быть таким:

expanded class REAL feature
... Объявления компонент такие же как и ранее ...
end

Все другие базисные типы объявляются подобным образом как развернутые.

Александр Шалухо
Александр Шалухо
Анатолий Садков
Анатолий Садков

При заказе pdf документа с сертификатом будет отправлен только сертификат или что-то ещё?