    Глава 24 

    Дополнительные концепции объектно-ориентированного подхода 

    24.1. Введение 

    В этой главе кратко рассматриваются отдельные концепции, которые в общем 
являются составной частью объектно-ориентированной методики. На самом деле, 
вопреки названию главы, каждая из этих концепций может рассматриваться 
независимо от того, является данная система объектно-ориентированной или нет. 
Например, языки программирования баз данных могут использоваться как для 
объектно-ориентированных, так и для реляционных баз данных (см., например, 
[24.2]). В этой связи необходимо отметить следующие концепции:	. 
    •  Языки программирования баз данных. 
    •   Версии. 
    •  Управление транзакциями. 
    •   Эволюция макета. 
    •  Повышение производительности. 
    Кроме того, в объектно-ориентированном контексте рассматриваются некоторые 
более традиционные аспекты управления базами данных. 
    •	"Связи" (т.е. ограничения целостности на уровне ссылок). 
    •	Общие ограничения целостности. 
    •	"Методы, которые охватывают классы" (т.е. функции с многими аргументами). 
    •	Незапланированные запросы. 
    При обсуждении этих и некоторых других вопросов особое внимание уделяется 
их взаимосвязи с некоторыми важными особенностями функционирования 
объектно-ориентированных систем. 

    24.2. Наиболее важные дополнительные концепции Языки программирования баз данных 

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

    634	Часть VI. Объектно-ориентированные системы 

    Такой подход, безусловно, обладает определенными преимуществами [24.2], 
например возможностью осуществления усовершенствованной проверки типов. В 
предлагаемой цитате из [22,12] отмечено еще одно важное достоинство: 
    "Благодаря простому единому языку не возникает никакого сопротивления 
из-за несовпадения процедурного языка программирования и внутреннего языка, 
ориентированного на работу с базами данных и обладающего декларативной семантикой". 
    Термин сопротивление из-за несовпадения используется для описания различий 
между типичными современными языками программирования, функционирующими на 
основе последовательной обработки записей, и реляционными языками типа SQL, 
функционирующими на основе последовательной обработки множеств. Очевидно, что 
такие различия на практике приводят к возникновению разнообразных проблем в 
реляционных программных продуктах. Для преодоления такого сопротивления, 
вместо перевода языка, ориентированного на работу с базами данных, на уровень 
функционирования на основе последовательной обработки записей (именно так 
работают объектно-ориентированные системы), в языках программирования вводятся 
инструменты для последовательной обработки множеств. Применение 
последовательной обработки записей в объектно-ориентированных языках 
отбрасывает нас к тем временам, когда использовались такие дореляционные 
системы, как IMS и IDMS. 
    В отношении последнего замечания следует отметить, что в действительности 
большинство существующих объектно-ориентированных языков полностью 
процедурные, т.е. они являются языками третьего поколения (типа 3GL — third 
generation language). В результате утрачиваются все преимущества реляционного 
подхода на основе последовательной обработки множеств. В частности, 
способность системы к оптимизации запросов пользователя заметно уменьшается, а 
значит, как и в дореляционных системах, производительность в значительной 
степени определяется самим пользователем (разработчиком программы или 
администратором базы данных). Более того, в большинстве современных систем 
используются несколько разные базовые языки, а не какой-то "единый язык" 
(например, унифицированный или какой-то другой), а в объектно-ориентированных 
системах в качестве этого "единого унифицированного языка" используется либо 
OPAL, либо C++, либо какой-то другой объектно-ориентированный язык, который 
может быть неизвестен широкому кру гу систем. 
    Здесь следует отметить, что, несмотря на существование нескольких 
объектно-ориентированных языков, на самом деле на рынке наиболее широко 
распространены языки OPAL (или какие-либо другие диалекты языка Smalltalk) и 
C++. Например, язык C++ [24.6, 24.10] поддерживается в большинстве современных 
коммерческих продуктов и фактически является стандартом (несмотря на то что не 
является "истинно объектно-ориентированным"). В настоящее время ведутся работы 
по созданию официального стандарта языка C++. 

    Замечание. При обсуждении данного вопроса в этом подразделе 
подразумевались программные языки, а не языки составления запросов. 
Действительно, как уже упоминалось в главе 22, идея незапланированных запросов 
находится в некотором противоречии с идеей инкапсуляции объектов. Однако на 
самом деле во многих объектно-ориентированных системах обеспечивается 
поддержка некоторой разновидности языка запросов. (Обычно для этого 
используется некоторый вариант языка SQL с названием типа Object SQL или OSQL, 
хотя следует предупредить читателя о том, что такие языки часто отличаются от 
привычного языка SQL.) Еще одним отличием от реляционных систем является то, 
что в объектно-ориентированных системах обычно используются два разных языка: 
один для программирования приложений, а другой для создания запросов. 

    Более подробно незапланированные запросы рассматриваются ниже в этой главе. 

    Глава 24. Дополнительные концепции объектно-ориентированного подхода	635 


    Версии 

    В разных сферах деятельности, например при разработке программного 
обеспечения, проектировании аппаратного обеспечения, создании документов и 
т.д. [24.4, 24.8, 24.9], часто приходится использовать концепцию нескольких 
версий определенного объекта. В некоторых объектно-ориентированных системах 
эта концепция поддерживается самым непосредственным образом. Причем под этим 
подразумевается исполнение некоторых основных операций. 
    •  Способность создать новую версию данного объекта за счет создания 
внешней копии объекта и перенесения ее за пределы базы данных на рабочую 
станцию пользователя, где в течение некоторого времени (например, часов или 
дней) эта версия может храниться или модифицироваться. 
    •  Способность установить данную версию объекта как текущую версию базы 
данных за счет перемещения ее с рабочей станции и возвращения обратно в базу 
данных (для чего может потребоваться выполнить операцию слияния различных версий). 
    •  Способность удалять (или архивировать) устаревшие версии. 
    •   Способность запрашивать историю создания версий для данного объекта. 
    Обратите внимание, что, как показано на рис. 24.1, история создания версий 
не обязательно может быть линейной (версия V.2 на этом рисунке разветвляется 
на две разные версии — V.3a и V.3b, которые впоследствии сливаются с 
образованием версии V.4). 

    Рис. 24.1. Типичная история создания версий объекта 

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

    Управление транзакциями 

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

    636  Часть VI. Объектно-ориентированные системы 

    1. Отмена транзакции (или откат) и возврат к начальному состоянию может 
привести к совершенно неприемлемой ситуации, когда значительная часть работы 
будет проделана впустую. 
    2.   Использование традиционных блокировок может привести к неприемлемо 
длительным задержкам (с ожиданием снятия этих блокировок). 
    В пункте 1 содержится намек на необходимость использования частичных 
откатов, а в пункте 2 — на необходимость разработки методов управления 
параллелизмом без использования блокировок. Этим требованиям удовлетворяют 
описанные ниже длительные и вложенные транзакции. 
    •  Длительные транзакции. Для обеспечения частичного отката можно 
воспользоваться концепцией точки сохранения для сохранения информации о 
текущем состоянии системы [13.10] и концепцией саги [13.8]. Более того, 
использование инструментов управления параллелизмом для многих версий также 
выглядит достаточно привлекательно, поскольку такой подход характеризуется 
рядом преимуществ. 
    • Операции чтения выполняются без задержки (в частности, они не 
задерживаются никакими параллельными длительными транзакциями). 
    • Операции чтения никогда не задерживают выполнение операций обновления (в 
частности, они не задерживают никаких параллельных длительных транзакций). 
    • Никогда не требуется выполнять откат для транзакции, которая выполняет 
только операции чтения. 
    • Тупиковые ситуации могут возникать только для транзакций обновления. 
    •   Вложенные транзакции. Концепция вложенных транзакций может 
рассматриваться как обобщенная идея точек сохранения [13.10]. Точки сохранения 
позволяют организовать транзакцию таким образом, что откат может быть выполнен 
для отдельных действий, а вложенные транзакции в целом образуют иерархию таких 
действий (рис. 24.2). Иначе говоря, для управления вложенными транзакциями 
используются следующие команды: 
    и т.д. 

    Рис. 24.2. Типичная транзакция с вложенной структурой 

    • Операция запуска транзакции BEGIN TRANSACTION распространяется на все 
подчиненные транзакции (т.е. если данная транзакция уже запущена, то 
исполнение операции BEGIN TRANSACTION приведет к запуску и дочерней транзакции). 
    • Операция завершения транзакции COMMIT TRANSACTION выполняется только в 
пределах родительской транзакции (если данная транзакция является дочерней). 
    • Операция отмены транзакции (или отката) РОТ т. RACK TRANSACTION приводит 
к возврату к исходному состоянию до запуска данной частной транзакции (включая 
дочерние и все другие подчиненные транзакции). 

    Глава 24, Дополнительные концепции объектно-ориентированного подхода 637 


    Эволюция макета 

    В традиционных СУБД обычно поддерживаются только очень простые изменения 
существующего макета СУБД (например, добавление нового атрибута к 
существующему базовому отношению). Однако в отдельных случаях требуется 
выполнить более сложные изменения, и в некоторых объектно-ориентированных 
прототипах эта проблема исследована достаточно глубоко. Причем в случае 
объектно-ориентированной системы эта проблема становится более сложной, 
поскольку сама по себе такая система имеет более сложный макет. 
    В [24.3] обсуждается система ORION, которая служит прототипом 
объектно-ориентированной системы, и приводится перечень некоторых основных 
возможных изменений макета. 
    •   Изменения объектного класса. 
    1.  Изменения экземпляра переменной: 
    • добавление экземпляра переменной; 
    • удаление экземпляра переменной; 
    • переименование экземпляра переменной; 
    • изменение принятого по умолчанию значения экземпляра переменной; 
    • изменение типа данных экземпляра переменной; 
    • изменение источника наследования экземпляра переменной. 
    2.  Изменения метода: 
    • добавление метода; 
    • удаление метода; 
    • переименование метода; 
    • изменение кода метода; 
    • изменение источника наследования метода. 
    •   Изменения иерархии классов (предполагается множественное наследование): 
    • добавление класса А к списку суперклассов класса В; 
    • удаление класса А из списка суперклассов класса В. 
    •   Изменения общего макета: 
    • добавление класса (в произвольном месте); 
    • удаление класса (в произвольном месте); 
    • переименование класса; 
    • разбиение класса; 
    • слияние классов. 
    Поскольку поддержка представлений в "объектно-ориентированную модель" 
обычно не включается, то не совсем ясно, насколько сильным окажется влияние 
таких изменений на прозрачность системы. Возможность внесения изменений в 
макет системы представляет собой достаточно сложную проблему именно из-за 
того, что в объектно-ориентированных системах осуществляется последовательная 
обработка записей. Как будет описано ниже, если при внесении изменений индексы 
или данные распределены по разным группам (кластерам), то никаких способов 
автоматически получить преимущества от таких изменений с помощью методов не существует. 

    Повышение производительности 

    Низкая производительность — один из самых существенных недостатков всех 
объектно-ориентированных систем. Причем существенное различие 
производительности (в некоторых случаях на несколько порядков) может привести 
к различиям 

    638	Часть VI. Объектно-ориентированные системы 

в функционалъном предназначении системы, поскольку для некоторых задач 
невозможно будет использовать данную систему, если ее производительность 
гораздо ниже предъявляемых требований. 
    Среди многочисленных факторов, влияющих на общую производительность 
системы, можно отметить следующие: 
    •   Кластеризация. Как показано в главе 18, физическая кластеризация 
логически связанных данных, размещенных на жестком диске, является одним из 
наиболее важных факторов повышения производительности системы. В 
объектно-ориентированных системах логическая информация (в отношении иерархии 
типов, иерархии контейнеров или других явно заданных связей между объектами) 
обычно основана на макете системы и используется в качестве приблизительного 
плана для физической кластеризации данных. Кроме того, часто рекомендуется, 
чтобы администратор базы данных сам осуществлял более явное и непосредственное управление. 
    •   Кэширование. Как предполагалось выше, объектно-ориентированные системы 
обычно используются в системах типа клиент/сервер, в которых пользователи 
"копируют" на свои рабочие станции сведения из базы данных на сервере и хранят 
их на своих рабочих станциях в течение некоторого времени. Очевидно, что в 
такой системе было бы полезно кэшировать логически связанные данные на рабочем 
месте клиента. 
    •   Процесс замены идентификаторов объекта адресами оперативной памяти при 
считывании объектов в оперативную память (и наоборот, когда объекты 
записываются обратно в базу данных). Преимущества такого метода очевидны для 
приложений, в которых обрабатываются достаточно "сложные объекты" и поэтому 
необходимо часто осуществлять поиск указателей. 
    В [22.2] обсуждается тестовая программа ОО1 для измерения 
производительности системы на основе базы данных, содержащей информацию о 
счетах и материалах (о ней можно прочесть также в [24.5]). Эта программа 
выполняет следующие операции: 
    1.  Неупорядоченное извлечение 1000 деталей с применением заданной 
пользователем функции для каждой детали. 
    2.  Неупорядоченная вставка 1000 деталей. 
    3.  Неупорядоченное разбиение деталей (до семи уровней) с применением 
заданной пользователем функции для каждой детали. 
    Согласно данным, опубликованным в [22.2], производительность некоторой (не 
сказано, какой) объектно-ориентированной системы на два порядка выше по 
сравнению с производительностью некоторой (не сказано, какой) современной 
реляционной системы, особенно при условии, что кэш уже заполнен данными (так 
называемый "теплый" доступ). Однако в той же работе отмечается, что "это 
отличие... не следует приписывать различию между собственно реляционной и 
объектно-ориентированной моделями. ...В основном эти различия обусловлены 
особенностями практического воплощения." Это утверждение может быть 
подкреплено тем фактом, что различия в производительности становились заметно 
меньше при увеличении размера базы данных (когда в кэш нельзя было поместить 
всю базу данных целиком). 

    24.3. Некоторые аспекты управления базами данных 

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

    Глава 24, Дополнительные концепции объектно-ориентированного подхода	639 

    •	Методы, охватывающие классы. 
    •	Незапланированные запросы. 
    •	Дополнительные аспекты. 

    Связи 

    Термин "связи" используется в объектно-ориентированных продуктах и 
литературе в основном для связей, представленных внешними ключами в 
реляционной базе данных. Но среди них следует различать перечисленные ниже типы. 
    1.	Связи типа подкласс-суперкласс (связь типа "ISA"). 
    2.	Связи типа один-ко-многим. 
    3.	Связи типа многие-ко-многим. 
    
    Рассмотрим их подробнее. 
    1.  Связи типа подкласс-суперкласс обычно представлены иерархиями классов, 
например с помощью выражения 

    . . .   RECTANGLE ISA   (   POLYGON  }    ... 

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

    ... DEPT ... ( ... EMPS REF ( SET ( REF ( ЕМР ))))..., 

    либо на основе метода "обратных переменных", который будет описан ниже. 
    3.  Связи типа многие-ко-многим обычно представлены либо на основе общего 
доступа к объекту, например объекты поставщиков и деталей могут "содержать" 
объекты поставок (и таким образом обладать совместным доступом к ним), либо на 
основе метода "обратных переменных". 

    Обратные переменные 

    Вновь рассмотрим пример с отделами и сотрудниками. Вместо принятия и 
использования концепции иерархии контейнеров можно определить два отдельных 
объектных класса (так же как и в реляционной базе данных) и в каждый объект 
отдела DEPT включить экземпляр переменной EMPS, соответствующей набору 
сотрудников в этом отделе, а также в каждый объект сотрудника ЕМР включить 
экземпляр переменной EDEPT, соответствующей отделу этого сотрудника: 

    ... DEPT ... ( ... EMPS REF ( SET ( REF ( ЕМР ) ) ) 
    INVERSE ЕМР.EDEPT ) ... ... ЕМР  ... ( ... EDEPT REF ( DEPT ) INVERSE 
DEPT.EMPS ) ... 

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

    ... S ... ( ... PARTS REF ( SET ( REF ( P ) ) ) 
    INVERSE P.SUPPS ) ... ... P ... ( ... SUPPS REF ( SET ( REF ( S ) ) ) 
    INVERSE S.PARTS ) ... 

    В этом примере обратные переменные являются переменными множества ссылок. 

    640	Часть VI. Объектно-ориентированные системы 

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

    SP.P# WHERE SP.S# = 'SI' SP.S# WHERE SP.P# = 'PI' 

    выглядят следующим образом: 

    S.PARTS.P# WHERE S.S# = 'SI' P.SUPPS.S# WHERE P.P# = 'PI' 

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

    Целостность на уровне ссылок 

    Теперь рассмотрим уже упомянутую ранее объектно-ориентированную поддержку 
целостности на уровне ссылок. Уровни такой поддержки могут быть самыми 
разными; например, ниже приводится классификация таких уровней, предложенная в 
работе Каттелла (Cattell) [22.2]. 
    •   Отсутствие системной поддержки. За поддержку целостности на уровне 
ссылок полностью несет ответственность пользователь и созданные им методы (как 
это и было определено в исходном варианте стандарта языка SQL). 
    •   Проверка достоверности ссылки. В системе проверяется соответствие типа 
данных для объекта, на который задана ссылка, однако в этом случае может быть 
запрещено удаление объектов (т.е. объекты, на которые нет ссылок, могут быть 
"собраны вместе в мусорной куче"), так же как это обусловлено в стандарте 
языка OPAL. Как уже объяснялось ранее, этот уровень поддержки эквивалентен (но 
лишь весьма приблизительно) правилам каскадного удаления (DELETE CASCADES) и 
"ограниченного" удаления (DELETE RESTRICTED) в иерархии контейнеров для 
подчиненных объектов без возможности совместного доступа. 
    •  Системная поддержка. На этом уровне отслеживание и обновление ссылок 
происходит автоматически (например, с помощью установки значения nil для 
ссылок на удаленные объекты.) Этот уровень в некоторой степени подобен правилу 
удаления DELETE NULLIFIES, используемому в реляционной системе. 
    •  "Настраиваемая семантика". Правило каскадного удаления DELETE CASCADES 
(применяемое за пределами иерархии контейнеров) может рассматриваться как 
пример "настраиваемой семантики". К моменту написания этой книги такие 
действия не поддерживались в объектно-ориентированных системах и должны были 
контролироваться соответствующими методами, т.е. с помощью процедур, созданных пользователем. 

    Целостность 

    Рассмотрим общие ограничения целостности на следующем примере: "Поставщики 
со статусом меньше 20 не должны поставлять более 500 деталей". Используя 
представленный в главе 16 язык описания ограничений целостности, это 
ограничение можно записать так: 

    Глава 24. Дополнительные концепции объектно-ориентированного подхода	641 
    21 Введение в системы баз данных 


    CREATE INTEGRITY RULE C95 
    IF S.STATUS < 20 AND S.S# = SP.S# THEN SP.OTY < 500 ; 

    В объектно-ориентированной системе, наоборот, это ограничение почти 
определенно будет приведено в действие с помощью некоторой процедуры. Такая 
процедура должна содержать по крайне мере следующие методы: 
    •	создание поставки; 
    •	изменение количества поставок; 
    •	изменение статуса поставщика; 
    •	указание соответствия некоторой поставки другому поставщику. 
    При внимательном изучении этого примера можно отметить некоторые особенности. 
    1.  При такой организации, очевидно, утрачивается возможность выполнения с 
помощью системы проверки соблюдения ограничений целостности. 
    2.   Как убедиться в том, что все эти методы содержат весь необходимый для 
поддержки целостности код? 
    3.   Как, например, при создании объектного класса для поставок 
предостеречь пользователя от случайного пренебрежения методом "создания 
поставки" и ошибочного непосредственного использования метода NEW (т.е. без 
проверки целостности)? 
    4.  Как добиться однообразия сообщений об ошибках 
    • для всех методов, которые предназначены для приведения в действие 
"одного и того же" ограничения, 
    • для всех ограничений (например, для всех ограничений целостности на 
уровне ссылок), которые находятся в строго заданном "родстве"? 
    5.   Как при изменении ограничений целостности найти и внести 
соответствующие изменения во все методы, в которых они были определены? 
    6.   Как убедиться в корректности кода, с помощью которого приводятся в 
действие ограничения целостности? 
    7.  Как выполнить проверку целостности для отложенных (во время 
исполнения) операций? 
    8.  Как узнать обо всех ограничениях, которые заданы для данного объекта 
или комбинации объектов? 
    9.  Будут ли ограничения целостности приводиться в действие во время 
загрузки системы или во время исполнения каких-то других действий? 
    10. Можно ли осуществить семантическую оптимизацию (т.е. упростить запросы 
с помощью ограничений целостности так, как это описано в главе 18)? 
    Кроме того, как повлияют перечисленные выше особенности на 
производительность работы во время создания приложения и при последующей 
работе с ним? 
    (Между прочим, в стандарте языка SQL/92 [8.1] предусмотрена декларативная 
поддержка ограничений целостности, и в СУБД разного типа— 
объектно-ориентированных или каких-либо других— она, по-видимому, также будет 
поддерживаться. Хотя последствия ее применения для объектно-ориентированных 
систем не совсем ясны.) 

    Замечание. Что касается функциональных зависимостей, то они являются 
особым видом ограничений целостности, с помощью которых система может 
осуществлять в определенной степени "разумное" управление. Однако в 
объектно-ориентированных системах не предусмотрена декларативная поддержка 
функциональных зависимостей. Тем не менее, некоторые специалисты рассматривают 
этот недостаток как достоинство. Как известно, функциональные зависимости 
могут быть весьма полезны при проектировании базы данных, однако в [22.12] 
отмечается, что "сложные данные в объектно-ориентированной системе могут быть 
непосредственно представлены без необходимости их нормализации...". 

    642	Часть VI, Объектно-ориентированные системы 

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

    Методы, охватывающие классы 

    Рассмотрим образовательную базу данных из главы 23 и запрос типа "Найти 
оценку, полученную сотрудником Е при изучении курса С", где Е\\С являются 
параметрами. Предположим, что для воплощения этого запроса был создан метод М. 
Частью какого объектного класса (класса сотрудников EMPLOYEE или класса курсов 
COURSE) должен быть метод М7 Как об этом узнает пользователь и каковы 
последствия такой реализации? 
    Эту же мысль можно сформулировать несколько иначе. Идея размещения 
некоторой функции или метода внутри объектного класса хороша только для 
функций, в которых используется один аргумент. При использовании функций с 
двумя или более аргументами существенно повышается степень произвола. 
Некоторые методы (например, метод NEW) на самом деле связаны с объектным 
классом не одним из его параметров, а результатом, что, в свою очередь, 
приводит к еще одной возможности произвола. 
    Здесь следует сделать небольшое отступление от этой темы. Почему все же 
методы размещаются внутри объектных классов? Ответ заключается в том, что эти 
методы нуждаются в привилегированном доступе, а именно доступе к внутреннему 
представлению (т.е. к частным экземплярам переменных) объектов данного класса. 
(Доступ к другим объектам осуществляется с помощью обычных методов GET и SET.) 
    Однако для осуществления привилегированного доступа можно было бы 
воспользоваться специальными методами обеспечения безопасности, (Обратите 
внимание, что здесь речь идет об объектно-ориентированных СУБД, в которых по 
историческим причинам обычно не предусматривались средства обеспечения 
безопасности.) Например, не лучше было бы для доступа к внутренней части 
объектов использовать не совместное размещение методов с объектными классами, 
а инструменты обеспечения безопасности? 
    По мнению автора, размещение методов внутри объектных классов не следует 
рассматривать как фундаментальный компонент "объектно-ориентированной модели". 
Следует отметить, что критика в данном случае относится не к самим методам, а 
к аспектам их размещения внутри объектных классов. 

    Незапланированные запросы 

    Выше уже несколько раз упоминалось, что в объектно-ориентированных 
системах существуют определенные трудности с обработкой незапланированных 
запросов (также называемых запросами типа ad hoc). В главе 22 отмечалось, что 
если для манипулирования объектами заданы только заранее определенные методы, 
то незапланированные запросы (не предусмотренные этими методами) невозможны, 
если только для объектов не задана некая специализированная структура. 
Например, если для объекта DEPT определены только методы HIRE_EMP (нанять 
сотрудника), FIRE_EMP (уволить сотрудника), CUT_BUDGET (урезать бюджет), то 
даже такой простой запрос, как "Кто является менеджером (начальником) отдела 
программирования", будет невозможно выполнить. 

    Глава 24, Дополнительные концепции объектно-ориентированного подхода	643 

    При внимательном изучении примеров, подобных приведенному выше, можно 
прийти к такому заключению. Для того чтобы иметь возможность выполнять 
незапланированные запросы для объектов некоторого класса, необходимо выполнить 
следующее: 
    1.  Определить и выполнить поддержку "семейства" всех существующих 
объектов этого класса. Это семейство в дальнейшем будет использовано в 
качестве области определения (диапазона) запросов, точно так же, как в 
реляционной системе используются базовые отношения. 
    2.  Определить общедоступный интерфейс для этого класса таким образом, 
чтобы обеспечить пользователю одно потенциальное представление объектов. 
    Например, рассмотрим класс точек POINT и класс линейных сегментов 
(отрезков) LINESEG. Допустим, что для х- и jy-координат точек, а также для 
начальных и конечных точек сегментов определены методы GET, на которые можно 
ссылаться произвольным образом в любых скалярных выражениях. Кроме того, 
предположим, что определено семейство всех линейных сегментов, а также 
семейство всех точек. В этом случае можно определить язык выполнения 
произвольных незапланированных запросов для этих объектов, например: 
    •	Найти все сегменты, которые начинаются в точке (0,0). 
    •	Найти все сегменты единичной длины. 
    •	Найти среднюю точку некоторого заданного сегмента. 
    Обратите внимание: здесь нигде не упоминалось, что внутренняя структура 
линейных сегментов может быть представлена параметрами для средней точки 
MIDPOINT, длины LENGTH и наклона SLOPE, а внутренняя структура точек — 
полярными координатами R и ТНЕТА. 
    Необходимо отметить следующие особенности: 
    1. Для выполнения самого запроса достаточно иметь методы GET, а для 
выполнения произвольных обновлений необходимы методы SET. 
    2.   В неоднозначном потенциальном представлении данного класса нет ничего 
плохого. Например, в случае класса POINT можно было бы определить методы GET_x 
и GET_y, а также методы GET_r и GET_9, поскольку для полярных координат запрос 
составить гораздо проще, чем для декартовых координат. Таким образом, 
пользователю будет известно, что каждая точка обладает свойствами х и у, а 
также свойствами г и 9. Однако это не означает, что все эти свойства являются 
взаимно независимыми, поскольку при изменении координат х и у будут также 
изменяться координаты гиб. (Более того, при задании такой организации 
следовало бы точно указать характер связи между координатами (х,у) и (г, 6), 
чтобы избежать нежелательных побочных эффектов.) 

    Замечание. Это не значит, что для данного класса следует определить только 
методы GET и SET. По крайней мере, нужно определить функцию-конструктор (т.е. 
определить метод NEW или какой-либо другой подобный ему) для создания новых 
экземпляров данного класса, а также соответствующую функцию-деструктор для 
удаления таких экземпляров. Кроме того, следует также задать методы для 
сравнения экземпляров класса, присвоения значений и т.д. 

    Дополнительные аспекты 

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

    644	Часть VI. Объектно-ориентированные системы 

    В некоторых объектно-ориентированных системах поддерживаются производные 
(общедоступные) экземпляры переменных: например, экземпляр переменной AGE 
(возраст) может быть производным от экземпляра переменной BIRTHDATE (дата 
рождения). Однако это понятие не совсем аналогично понятию представления. 
Замечание. Этот вопрос связан с общим понятием производных объектов и более 
подробно рассматривается в главе 25 и в [24.1], где описываются некоторые 
научные идеи относительно поддержки представлений в объектно-ориентированных системах. 
    •  Каталог. Где и в каком виде находится каталог в 
объектно-ориентированной системе? Существуют ли какие-либо стандарты в 
отношении каталогов? 
    Между прочим, именно эти вопросы позволяют продемонстрировать существенное 
различие между объектно-ориентированной и реляционной СУБД. Реляционная СУБД 
предстает перед пользователем в готовом к употреблению виде, т.е. как только 
она установлена, пользователь может приступать к созданию баз данных, 
написанию приложений, запуску запросов и т.д. Объектно-ориентированная 
система, наоборот, представляет собой некую разновидность набора инструментов 
для работы с СУБД, Дело в том, что в ней содержится целый набор "строительных 
блоков" (инструментов поддержки библиотек объектов, компиляторы методов и 
т.д.), которые могут использоваться техническим персоналом (т.е. специалистами 
в области баз данных) для конструирования СУБД в более привычном смысле этого 
слова, В частности, эти специалисты в области баз данных должны создать 
соответствующий каталог для разрабатываемых ими объектов и методов. Более 
того, сконструированная таким образом СУБД будет больше ориентирована на 
работу конкретного проф иля. Например, она может быть предназначена для работы 
с некоторым набором приложений САПР/АСУП и совершенно непригодна для 
медицинских приложений. 
    •  Отсутствующая информация. Проблема отсутствующей информации еще далека 
от полного разрешения в реляционных системах (см. главу 20). Что касается 
области изучения объектно-ориентированных подходов, то в ней эта проблема 
попросту игнорируется, а это означает ощутимое отставание по данному вопросу в 
отличие от области изучения реляционных баз данных. В качестве примера можно 
привести следующий вопрос: "Является ли значение nil членом каждого класса?" [22.12]. 
    •  Замыкание. Какое понятие объектно-ориентированной концепции 
соответствует свойству замыкания из реляционной концепции? 

    24.4. Резюме 

    Ниже перечислены основные вопросы, которые рассматривались в этой главе. 
    • Языки программирования баз данных. Здесь было представлено понятие 
сопротивления из-за несовпадения и отмечалось, что для решения этой проблемы 
следует не опускать уровень языка баз данных до уровня последовательной 
обработки записей, а скорее повышать уровень языка программирования до уровня 
последовательной обработки множеств. Действительно, объектно-ориентированные 
языки являются процедурными, но, по сути, это серьезный недостаток, поскольку 
в значительной мере сказывается на возможностях оптимизации. 
    •  Версии. Были кратко описаны идеи поддержки версий и конфигураций, а 
также основные понятия внешнего копирования объектов базы данных и их 
возвращения обратно в базу данных. 
    •   Управление транзакциями. Исполнение объектно-ориентированных 
транзакций может продолжаться не миллисекунды, а часы и даже дни. Поэтому для 
обеспечения нормальной работы желательно организовать поддержку длительных или 

    Глава 24, Дополнительные концепции объектно-ориентированного подхода	645 

вложенных транзакций. В связи с этим рассматривались способы управления 
параллелизмом для многих версий и отмечались некоторые их преимущества. 
    •   Эволюция макета, В этой главе обсуждалась классификация возможных 
изменений макета СУБД. Указывалось, что проблема эволюции макета особенно 
сложна в объектно-ориентированных системах, поскольку сам по себе макет очень 
сложно устроен. Кроме того, в "объектно-ориентированной модели" обычно не 
предусмотрена поддержка представлений, а код объектно-ориентированной системы 
основан на последовательной обработке записей. 
    •  Повышение производительности. Подчеркивалось, что низкая 
производительность — один из самых существенных недостатков 
объектно-ориентированных систем. Рассматривались некоторые основные факторы, 
влияющие на производительность, а именно кластеризация, кэширование и 
двухсторонняя замена идентификаторов и адресов. При этом кратко упоминалась 
программа тестирования производительности ОО1. 
    •  Связи. Термин "связи" в объектно-ориентированном контексте используется 
обычно для проведения аналогии с понятием связей между внешними ключами, 
используемым в реляционном контексте. При этом следует различать связи типа 
подкласс-суперкласс, один-ко-многим, многие-ко-многим. В частности, кратко 
рассматривались обратные переменные и различные уровни возможной поддержки 
целостности на уровне ссылок: без системной поддержки, с проверкой 
достоверности ссылок, с системной поддержкой и на основе "настраиваемой 
семантики". Там, где это возможно, все понятия сравнивались с аналогичными 
понятиями из области реляционных подходов. 
    •   Целостность. Отдельно была подвергнута критике способность 
объектно-ориентированных систем управлять ограничениями целостности только 
процедурно (с помощью методов), а не декларативно. 
    •   Методы, охватывающие классы. Кроме того, было высказано несколько 
критических замечаний в отношении размещения методов внутри классов в 
объектно-ориентированных системах. Это особенно касалось тех моментов, когда 
метод может быть размещен в разных классах совершенно произвольным образом. 
При этом было сделано предложение, чтобы на самом деле при использовании 
некоторых инструментов обеспечения безопасности для управления доступом к 
внутренней структуре объектов можно было избегать размещения методов внутри классов. 
    •   Незапланированные запросы. Был предложен конкретный способ обеспечения 
внутри объектно-ориентированных систем полной поддержки незапланированных 
запросов. Ключевым элементом в нем является обеспечение единого потенциального 
представления объектов для пользователя (благодаря соответствующим методам GET). 
    • Дополнительные аспекты. Наконец, в заключение было приведено несколько 
замечаний относительно представлений, каталога, отсутствующей информации и 
замыкания. В частности, отмечалось коренное отличие объектно-ориентированной 
СУБД от реляционной, которое заключается в том, что реляционная СУБД предстает 
перед пользователем в готовом к употреблению виде, а объектно-ориентированная 
система, наоборот, представляет собой некую разновидность набора инструментов 
для создания специализированных СУБД. 
    О последней особенности следует сказать несколько дополнительных слов. 
Можно было бы подумать, что это отличие объясняется разным происхождением этих 
двух методик. Однако, по мнению автора, объектно-ориентированная методика 
создания баз данных, вероятнее всего, возникла благодаря желанию отдельных 
программистов (продиктованному самыми разными причинами) хранить созданные ими 

    646	Часть VI. Объектно-ориентированные системы 

специализированные объекты в постоянной памяти. При этом под такой 
"постоянной памятью" подразумевается, например, база данных, но 
специализированного назначения, а потому в ней совершенно исключается всякая 
возможность исполнения незапланированных запросов. Потому, спустя некоторое 
время после реальной работы с такой базой данных, были обнаружены следующие особенности: 
    1.  Такая база данных предполагает совместный доступ со стороны нескольких приложений. 
    2.  Поэтому для хранящихся в ней данных следовало бы задать: 
    • некоторые независимые от отдельного приложения ограничения целостности; 
    • некоторые правила обеспечения безопасности. 
    Впоследствии, после представления основной идеи хранения объектов в базе 
данных, эти особенности были рассмотрены и реализованы как усовершенствования 
и добавления к исходной "объектно-ориентированной модели". 
    Хотя приведенные выше рассуждения несколько выходят за рамки этой книги, 
все же, по мнению автора, они помогают разъяснить разницу между 
объектно-ориентированными и традиционными системами управления базами данных. 

    Упражнения 

    24.1. Как вы понимаете термины версия и конфигурация!     
    24.2. Почему рекомендуется обеспечивать поддержку длительной и вложенной транзакции? 
    24.3. Опишите в общих чертах метод воплощения управления параллелизмом для 
многих версий. 
    24.4. Рассмотрите основные факторы, оказывающие влияние на 
производительность, которые кратко описаны в этой главе. Правда ли то, что они 
характерны только для объектно-ориентированных систем? Обоснуйте свой ответ. 
    24.5. В объектно-ориентированных системах ограничения целостности 
поддерживаются процедурно, т.е. с помощью методов, за исключением поддержки 
ограничений целостности на уровне ссылок, которая осуществляется декларативно, 
В чем состоит преимущество процедурного способа поддержки ограничений 
целостности? Почему ограничения целостности на уровне ссылок поддерживаются иначе? 
    24.6. Объясните смысл концепции обратных переменных. 
    24.7. Рассмотрите концепцию эволюции макета, представленную в этой главе. 
Какие элементы этой классификации можно соотнести с аналогичными понятиями 
реляционной системы? Что это за понятия? 
    24.8. Какими могут быть последствия внесения изменений в макет для уже 
имеющихся данных? 
    24.9. Исследуйте любую доступную вам объектно-ориентированную систему. 
Какой язык программирования поддерживается в такой системе? Поддерживается ли 
в этой системе язык запросов? Если да, то какой? Является ли он, по вашему 
мнению, более мощным, чем язык SQL? Поддерживаются ли в этой системе версии и 
конфигурации? Если да, то в какой степени пользователь может управлять 
версиями и запрашивать историю создания версий? Поддерживаются ли в такой 
системе длительные или вложенные транзакции? Обладает ли такая система 
способностью к эволюции макета? Как организован каталог системы? Как 
пользователь запрашивает каталог? Предусмотрена ли в такой системе поддержка 
представлений? Если да, то в какой степени (например, поддерживается ли в ней 
обновление представлений)? Как организовано управление отсутствующей информацией? 

    Глава 24, Дополнительные концепции объектно-ориентированного подхода	647 


    Список литературы 

    Кроме приведенного ниже списка, рекомендуется также просмотреть списки 
литературы в главах 22 и 23. 
    24.1. Abiteboul S., Bonner A. Objects and Views // Proc. ACM Intern. Conf. 
on Management of Data. — Denver, Colo., 1991. 
    В работе предлагается метод использования представлений в 
объектно-ориентированных системах. В ней впервые было принято во внимание 
использование поведенческих методов. 
    24.2. Atkinson M.P., Buneman O.P. Types and Persistence in Database 
Programming Languages // ACM Сотр. Surv. — 1987. — 19, № 2. 
    Эта статья рекомендуется в качестве вводного пособия по изучению языков 
программирования баз данных. 
    24.3. Banerjee J. et al. Data Model Issues for Object-Oriented 
Applications // ACM TODS. — 1987. — 5, № 1. (Эта работа также опубликована в 
М. Stonebraker (ed.). Readings in Database Systems. — San Mateo, Calif.: 
Morgan Kaufmann, 1988, а также в [22.16].) 
    24.4. Bjornerstedt A., Hulten C. Version Control in an Object-Oriented 
Architecture. (Опубликована в [22.9].) 
    24.5. Cattell R.G.G., Skeen J. Object Operations Benchmark // ACM TODS. — 
1992.—17, № 1. 
    24.6. Ellis M.A., Stroustrup B. The Annotated C++ Reference Manual. — 
Reading, Mass.: Addison-Wesley, 1990. 
    24.7. Jagadish H.V., Xiaolei Q. Integrity Maintenance in an 
Object-Oriented Database // Proc 18th Intern. Conf. on Very Large Data Bases. 
— Vancouver, Canada, 1992. 
    В работе предлагается декларативный метод указания ограничений целостности 
в объектно-ориентированных системах. При этом описано, как компилятор 
ограничений помещает в методы соответствующих классов необходимый код проверки целостности. 
    24.8. Katz R.H., Chang E. Managing Change in a Computer-Aided Design 
Database // Proc. 13th Intern. Conf. on Very Large Data Bases. — Brighton, UK, 1987. 
    24.9. Roddick J.F. Schema Evolution in Database Systems — An Annotated 
Bibliography //ACM SIGMOD. — 1992. — Record21, №4. 
    24.10. Stroustrup    B.    The    C++    Programming    Language. —    
Reading,    Mass.: Addison-Wesley, 1986. 

    Ответы к некоторым упражнениям 

    24.3. Прежде всего, метод воплощения управления параллелизмом для многих 
версий требует выполнения перечисленных ниже условий, взятых из [21.14]. 
    1.  Для каждого объекта данных в системе должен находиться стек 
завершенных версий (каждый элемент стека содержит значение этого объекта, а 
также идентификатор транзакции, которая установила это значение; т.е. каждый 
элемент стека, по сути, содержит указатель на соответствующий элемент файла 
протокола). Стек содержит все сведения в обратном хронологическом порядке, 
причем последний помещенный в него элемент может быть извлечен из стека первым. 
    2.  В системе также должен содержаться список идентификаторов всех 
завершенных транзакций. 

    648	Часть VI. Объектно-ориентированные системы 


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

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

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

    Глава 24. Дополнительные концепции объектно-ориентированного подхода	649 

