Главная » SQL, Базы данных » ОБЪЕКТЫ, КЛАССЫ, МЕТОДЫ И СООБЩЕНИЯ

0

Ниже представлены некоторые основные термины и концепции объектного подхода, а именно — сами объекты (естественно), объектные классы, методы и сообщения. Там, где это возможно и уместно, данные понятия сравниваются с более знакомыми понятиями. Фактически в весьма приблизительной форме объектную терминологию вполне можно соотнести с терминологией традиционного программирования (рис. 25.3).

Рис. 25.3. Объектная терминология (сводка)

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

1   Для  этого  решения  требуется  применение типов,  определяемых пользователем. Язык  SQL  ко  времени появления на рынке первых объектных систем не поддерживал типы, определяемые пользователем; теперь такая поддержка в них предусмотрена. В действительности, язык SQL в настоящее время поддерживает несколько средств, благодаря которым он становится в определенной степени "объектно-ориентированным". Но мы намеренно отложим обсуждение этих средств до следующей главы.

[25.10], [25.39] и [25.42]). Например, не существует абстрактной, формально  определенной "объектной модели данных", нет согласия даже применительно к неформальной модели. (Поэтому в данной книге термин "объектная модель" приводится в кавычках.) Также, как это ни странно, нет четкого разграничения  между уровнями абстракции, в частности (ключевого!) разграничения между самой моделью и ее реализацией.

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

Обзор объектной технологии

Вопрос: Что такое объект? Ответ: Все что угодно!

Основной догмат объектного подхода— "объектом является все что угодно"  (или иногда говорят "все что угодно — объект первого класса"). Одни объекты являются неизменяемыми; в качестве примера можно привести целые числа (например, 3, 42) и символьные строки (например, "Mozart", "Hayduke Lives!"). Другие объекты — изменяемые; примерами могут служить объекты, представляющие отделы и служащих, которые упоминались в начале раздела 25.1. Согласно традиционной терминологии, неизменяемые объекты соответствуют  значениям, а изменяемые — переменным2, где рассматриваемые значения и переменные могут иметь произвольную сложность (т.е. такие объекты могут содержать любое количество типов данных, имеющихся в обычных языках программирования, и конструкторов этих типов — чисел, строк, списков, массивов, стеков и т.д.).

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

Каждый объект имеет тип (в объектной терминологии — класс). Отдельные объекты иногда называются экземплярами объектов (или просто экземплярами), чтобы их можно

было отличить от соответствующего объектного типа или класса. Обратите внимание на то, что термин тип здесь используется в смысле, принятом в традиционном программировании (как в главе 5), в частности, этот термин охватывает и набор операторов (в объектной терминологии — методов), которые могут применяться к объектам рассматриваемого типа. Операторы только чтения и операторы обновления  называются, соответственно, наблюдателями (observer) и модификаторами (mutator).

Примечание. На самом деле, в некоторых объектных системах понятия типов и классов различаются. Такие системы кратко будут рассмотрены в разделе 25.3, но пока мы будем использовать эти понятия как взаимозаменяемые.

2 Заметим, однако, что термин переменная без дополнительного уточнения в объектном контексте часто  используется для обозначения, в очень узком смысле этого слова, некоторой переменной (либо  локальной переменной, либо переменной экземпляра), которая содержит идентификатор  объекта (о чем пойдет речь далее в этом разделе).

Объекты инкапсулированы. Это означает, что физическое представление, т.е.  внутренняя структура объекта, например, объекта DEPT (Отдел), остается скрытой от пользователей. В действительности, пользователю известно только то, что объект способен выполнять некоторые операции (методы). Например, к объектам DEPT могут применяться методы HIRE_EMP (Нанять сотрудника), FIRE_EMP (УВОЛИТЬ сотрудника), CUT_BUDGET (Урезать бюджет) и т.д. Также обратите внимание на то, что к данным объектам могут применяться ТОЛЬКО те операции,  которые упомянуты среди этих методов. Доступ к внутреннему представлению таких объектов разрешен только коду, с помощью которого эти методы реализованы, т.е., употребляя жаргон, можно сказать, что эти и только эти методы могут "взломать инкапсулированный объект"3, но, безусловно, данный код также невидим для пользователей.

Следует отметить, что в литературе, посвященной объектному  программированию, понятие инкапсуляции фактически трактуется во многом по-разному. Один из подходов, который представляется наиболее обоснованным, принятый в этой книге, состоит в том, что объект считается инкапсулированным тогда и только тогда, когда он является скалярным в том смысле, который был указан в главе 5 (это означает, что он не имеет компонентов, доступных пользователю). В связи с этим термины инкапсулированный и скалярный обозначают полностью одно и то же понятие. Поэтому следует отметить, что, согласно этому определению, некоторые объекты коллекций (см. раздел 25.3), безусловно, нельзя назвать скалярными, и поэтому инкапсулированными. В отличие от этого, некоторые авторы категорически заявляют, что все объекты инкапсулированы, а такая позиция неизбежно ведет к существенным противоречиям. Другие авторы считают, что понятие инкапсуляции означает не только сокрытие внутренней структуры объекта, но и физическую увязку соответствующих методов с объектом или классом рассматриваемого объекта (т.е. физическое включение методов в состав объекта). По мнению автора, в последней интерпретации не учитываются различия между моделью и реализацией;  безусловно, именно эта путаница является еще одной из причин, по которой (как указано в главе 5) автор предпочитает вообще не использовать термин инкапсуляция, но в настоящей главе нам, безусловно, придется время от времени сталкиваться с этим термином.

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

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

3  Как было указано в главах 5 и 20, автор рекомендует придерживаться более строгих требований. Это означает, что нарушать правила инкапсуляции должно быть разрешено только тем операторам, которые предписаны моделью (в частности, селекторам и операторам  "ТНЕ_");  все остальные операторы должны быть реализованы в терминах этих операторов. При разработке кода необходимо соблюдать все предосторожности! Но поскольку нет согласия в части определения объектной модели, специалисты по объектным системам не пришли к единому мнению и в отношении того, какими должны быть операторы, предписанные "моделью".

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

■   Открытый интерфейс состоит из определений интерфейсов для методов  данного объекта. Эти определения соответствуют тому, что в главе 20 было названо сигнатурами спецификации. Но, как будет показано ниже, в объектных системах обычно требуется, чтобы такие сигнатуры были связаны лишь с одним конкретным целевым типом или классом. А в главе 20 ни о чем подобном не было и речи, но мы не считаем, что такое требование необходимо или обязательно [3.3]. Как уже отмечалось, код, который  реализует методы объекта, как и переменные экземпляра, скрыт от пользователя.

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

Методы вызываются с помощью сообщений, которые, по сути, являются  вызовами функций и имеют единственный синтаксически выделенный  формальный параметр — получатель, или цель. Например, ниже приводится сообщение, записанное с использованием гипотетического синтаксиса и  предназначенное для передачи указания о приеме сотрудника Е на работу в отдел D.

D  HIRE_EMP    (   Е   )

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

HIRE_EMP   (   D,    Е  )

4  Выделение одного фактического параметра в качестве особого может упростить  выполнение системой процесса связывания на этапе прогона, который был описан в главе 20. Однако такой подход имеет и целый ряд недостатков [3.3]; не последним из них можно назвать то, что для программиста, разрабатывающего конкретный метод, усложняется работа по  написанию  кода реализации. Еще один недостаток состоит в том, что выбор целевого  фактического параметра (разумеется, в том случае, если есть из чего выбирать, т.е. если имеется несколько фактических параметров) осуществляется произвольно.

Для удобства в любой объектной системе обычно заранее предусмотрен некоторый набор встроенных классов и методов. В частности, в ней почти всегда присутствуют такие классы, как INTEGER (с методами "=", "<", "+", "-" и т.д.), CHAR (С методами "=", "<", " | |", SUBSTR и т.д.), а также другие классы.  Безусловно, в системе предоставляются возможности и для опытных пользователей, которые могут создать собственные классы и методы.

Переменные экземпляра

Рассмотрим более подробно концепцию переменных экземпляра, в отношении которой у специалистов все еще нет единства мнений. Как утверждалось ранее,  в истинно объектной системе переменные экземпляра должны быть полностью скрыты от пользователя, но, к сожалению, большинство систем не являются действительно объектными. Поэтому на практике необходимо различать открытые и закрытые переменные экземпляра; последние действительно скрыты для внешнего мира, тогда как первые— нет.

Предположим, что имеется объектный класс отрезков прямых (line segment —  Is).

Будем считать, что каждый отрезок имеет начало (точка BEGIN) и конец (точка  END) (напомним, что аналогичный пример использовался в главе 5). Чтобы "получить" значения координат этих точек для заданного сегмента Is, обычно используются выражения наподобие Is. BEGIN и Is.END. Таким образом, BEGIN и END — открытые переменные

экземпляра (отметим, что по определению доступ к таким переменным должен осуществляться с помощью специального синтаксиса — обычно используется точка после имени объекта, как в нашем примере). Если физическое представление отрезков прямых заменить,  например,  комбинацией  координат  средней  точки  (MIDPOINT),  длины  отрезка (LENGTH) и его наклона (SLOPE), любая программа, которая содержит такие выражения, как 1s.BEGIN и 1s.END, перестанет работать. Иными словами,  будет утрачена независимость от данных.

Обратите внимание на то, что открытые переменные экземпляра не являются логически необходимыми. Предположим, что для получения значений переменных  экземпляра  отрезка  прямой  определены  методы  GET_BEGIN,  GET_END,   GET_MIDPOINT, GET_LENGTH и GET_SLOPE. Тогда пользователь сможет "получить" значения координат начала,  конца,  средней  точки  отрезка  Is,  его   длины  и  наклона,  вызвав  методы GET_BEGIN{1s) ,    GET_END(1s),    GET_MIDPOINT(1s),   GET_LENGTH(1s)   И GET_SLOPE(1s),  соответственно.  Но  в  этом  случае  уже  не  имеет  значения,  каково действительное  физическое  представление  отрезка  —  вполне  достаточно,  чтобы  при каждом его изменении  соответствующим образом были изменены и методы GET. Более того, не было бы  ошибкой, если бы пользователю разрешалось применять выражения наподобие 1s.BEGIN в качестве сокращения для выражения вызова метода GET_BEGIN( 1s). Обратите внимание на то, что для использования такого сокращения объект вовсе не обязательно должен содержать открытую переменную экземпляра BEGIN. К сожалению, в  реальных  системах  обычно  не  придерживаются  такого  подхода.  Как правило,  все открытые  переменные  экземпляра  фактически  отражают   физическое  представление объекта   (по   крайней   мере,   частично,   хотя    могут    существовать   и   некоторые дополнительные переменные экземпляра, которые являются действительно закрытыми и скрытыми). Поэтому в соответствии со сложившейся практикой будем считать, что, если не   указано   иное,   объекты    предоставляют   определенные   открытые   переменные экземпляра, хотя это понятие логически излишне.

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

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

Идентификатор объекта

Каждый объект обладает уникальным идентификатором объекта (Object ID — OID). Такие примитивные (неизменяемые) объекты, как целое число 42, являются  самоидентифицирующимися, т.е. они сами являются собственными идентификаторами объекта.

►Изменяемые объекты, напротив, имеют в качестве идентификаторов адреса (концептуальные). Эти адреса можно использовать во всей базе данных как указатели  (концептуальные) на соответствующие объекты. Адреса объектов пользователю непосредственно не предоставляются, но они могут быть присвоены, например, переменным программы и переменным экземпляров в других объектах. Обсуждение этого вопроса будет продолжено в разделах 25.3 и 25.4.

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

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

внешне различить оба объекта? (Более подробно этот вопрос описан в [6.3], [6.6] и особенно-в [25.17].)

Источник: Дейт К. Дж., Введение в системы баз данных, 8-е издание.: Пер. с англ. — М.: Издательский дом «Вильямс», 2005. — 1328 с.: ил. — Парал. тит. англ.

По теме:

  • Комментарии