Термин "объект" в программной индустрии впервые был введен в языке Simula (1967 г.) и означал какой-либо аспект моделируемой реальности. Сейчас под объектом понимается "нечто, имеющее четко определенные границы" (определение известного американского специалиста Г.Буча). Объекты, обладающие одинаковыми свойствами, составляют классы (например, курица, пингвин и чайка - объекты класса "птицы"). Обычно класс описывается как новый тип данных, а объекты (экземпляры класса) - определенные на его основе переменных.
Сразу же необходимо заметить, что общепринятого определения "объектно-ориентированной модели данных" не существует. Сейчас можно говорить лишь о неком "объектном" подходе к логическому представлению данных и о различных объектно-ориентированных способах его реализации.
Мы знаем, что любая модель данных должна включать три аспекта: структурный, целостный и манипуляционный. Посмотрим, как они реализуются на основе объектно-ориентированная парадигмы программирования:
Структура:
Структура объектной модели описываются с помощью трех ключевых понятий:
Class Point { // вводим новый тип данных - объект "точка" X,Y : int; // данные объекта - координаты точки ......... Point(X : int, Y : int); // конструктор объекта - процедура, вызываемая при // определении переменной на базе объекта и // присваивающая значения его данным ......... Draw(); // метод "нарисовать точку" Erase(); // метод "стереть точку" Move(newX,newY); // метод "переместить точку" (изменяет данные объекта) int GetX(); // метод "получить значение поля X" int GetY(); // метод "получить значение поля Y" ......... // все методы должны быть описаны, например // реализация метода Move: Move(newX : int, newY : int) { X=newX; // запись новых данных в объект Y=newY; // } } // конец описания объекта Begin // основная процедура программы Point A(0,0); // создать новый объект и присвоить ему данные for i=1 to 100 // создать цикл A.Draw(); // нарисовать точку A.Hide(); // стереть точку A.Move(i,i*10); // присвоить экземпляру объекта новые данные endfor; // print(A.GetX(),A.GetY()); // получить и напечатать данные объекта End.Из этого примера видно, что мы не можем напрямую обратиться к данным объекта, а должны вызывать метод
Move
для изменения его данных и GetX, GetY
для
считывания значений этих данных. Т.е. объект скрывает свою внутренню структуру, именно это
свойство и называется "инкапсуляцией".Class Circle extend Point { // создаем новый объект "окружность", наследующий // свойства объекта "точка" Radius : int; // добавляем новое поле "радиус", поля X и Y наследуются // от родительского объекта ............. Circle(X:int,Y:int,Radius:int); // конструктор нового объекта ............. Draw(); // переопределяем некоторые методы Hide(); // родительского объекта, метод Move наследуется ............. ChangeRadius(Radius); // вводим новый метод "изменить радиус" ............. GetRadius(); // вводим новый метод "получить значение радиуса" // методы GetX и GetY наследуются от родительского // объекта }
Begin Point A(100,100); Circle B(200,200,50); A.Draw(); // рисует точку B.Draw(); // рисует окружность End.
Целостность данных:
Для поддержания целостности объектно-ориентированный подход предлагает использовать следующие средства:
Средства манипулирования данными:
К сожалению, в объектно-ориентированном программировании отсутствуют общие средства манипулирования данными, такие как реляционная алгебра или реляционное счисление. Работа с данными ведется с помощью одного из объектно-ориентированных языков программирования общего назначения, обычно это SmallTalk, C++ или Java.
Подведем теперь некоторые итоги:
В объектно-ориентированных базах данных, в отличие от реляционных, хранятся не записи, а объекты. ОО-подход представляет более совершенные средства для отображения реального мира, чем реляционная модель:
Появление объектно-ориентированных СУБД вызвано потребностями программистов на ОО-языках, которым были необходимы средства для хранения объектов, не помещавшихся в оперативной памяти компьютера. Также важна была задача сохранения состояния объектов между повторными запусками прикладной программы. Поэтому, большинство ООСУБД представляют собой библиотеку, процедуры управления данными которой включаются в прикладную программу. Примеры реализации ООСУБД как выделеного сервера базы данных крайне редки.
В качестве примера рассмотрим объектно-ориентированную СУБД ObjectStore, которая обеспечивает долговременное хранение в базе данных объектов, созданных программами на языках C++ и Java. Вся работа с объектами ведется обычными средствами включающего ОО-языка. При этом СУБД как бы расширяет виртуальную память операционной системы. Происходит это следующим образом. Когда прикладная программа обращается к объекту, то ищет его по адресу в оперативной памяти. Нужная страница оперативной памяти может быть вытеснена в виртуальную память (область хранения неиспользуемых страниц оперативной памяти на диске). Если объекта с таким адресом в виртуальной памяти не существует, то операционная система генерирует ошибку. СУБД эту ошибку перехватывает и извлекает объект из базы данных.
ObjectStore поддерживает транзакции (в данный момент времени может существовать только одна транзакция), допускает методы доступа: хеш-таблица для несортированных данных и B-дерево для сортированных, также возможно использование SQL.
Бесплатную копию ObjectStore можно получить с веб-сервера компании Object Design Inc.
ODMG (Object Data Management Group) - консорциум поставщиков ООБД и других заинтересованных организаций, созданный в 1991 г. Его задачей является разработка стандарта на хранение объектов в базах даннных. В настоящее время опубликован вторая версия стандарта, которую так и называют ODMG 2.0. Рассмотрим кратко основные положения этого документа.
Стандарт на хранение объектов ODMG 2.0 разработан на основе трех существующих стандартов: управление базами данных (SQL), объекты (стандарты OMG - Object Management Group) и стандарты на объектно-ориентированные языки программирования (C++, Smalltalk, Java).
ODMG добавляет возможности взаимодействия с базами данных в объектно-ориентированные языки программирования: определяются средства долговременного хранения объектов и расширяется семантика языка, вносятся операторы управления данными. Стандарт состоит из нескольких частей:
Попытки совместить средства манипулирования данными реляционной модели и способы описания внешнего мира объектно-ориентированной модели получили развитие в языке SQL-3. (см. статью Д.Бича К объектным базам данных, опубликованную в журнале "Открытые системы" N 4 за 1994 г.). Здесь мы рассмтотрим только предлагаемые способы определения данных.
Разработчики SQL-3 считают, что харакетристики объекта определяется описанием строки таблицы. Поэтому, вводится специальная возможность описания нового типа данных:
Create type Address ( number char (6), street char (30), aptno integer, city char (30), state char (2), zip integer );На основе нового типа могут быть определены таблицы, например:
Create table Addresses of Address;
Новые типы допускается использовать и для определения столбцов (т.е. игнорируется требование атомарности атрибутов реляционной модели):
Сreate table People of new type Person ( name char (30), address Address, birthdate date, );
Наследование определяется с помощью фразы under.
Create type Employee under Person ( empno char(10), dept ref(Department) );Здесь атрибут dept является ссылкой на объект, хранящийся в таблице Department. Т.е. в понятиях реляционной модели в этом столбце должен быть записан внешний ключ, указывающий на на одну из строк таблицы Department. На самом деле, в SQL-3 предполагается, что каждый объект имеет уникальный идентификатор - OID, именно он используется при создании ссылок на объекты.
Также в операторе CREATE TABLE можно определить и методы доступа к вновь созданным типам данных:
Create table People of new type Person ( name char(30), address Address, birthdate date function age(:р ref(Person)) return date; begin current_age:=:р.birthdate-current_date; return current_age; end; );В этом примере задана функция age, которая вычисляет текущий возраст объекта типа Person, хранимого в таблице People. К данной функции можно обращаться из оператора SELECT.
Здесь свойства SQL-3 рассмотрены весьма кратко. Более полное представление о них можно получить из указанной статьи Д.Бича, а также из литературы, посвященной возможностям СУБД Oracle 8, которая подерживает данный язык.
Заметим, что К.Дейт придерживается мнения, что областью определения объекта надо считать не строку, а столбец реляционной таблицы. Подробнее об этом см. в его книге.
Еще один подход к объединению свойств реляционной модели и объектно-оринетированного программирования обсуждается в следующем параграфе.