Объектно-ориентированная модель — студенческий портал

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

В начале компьютерной эры программирование обычно ограничивалось программированием на машинном языке. Машинный язык означает те наборы инструкций, которые специфичны для конкретного компьютера или процессора и имеют форму 0 и 1. Это последовательности битов (0100110…). Но довольно сложно написать программу или разработать программное обеспечение на машинном языке.

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

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

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

Объектно-ориентированная модель - Студенческий портал

Структурированное программирование — Основным принципом подхода структурированного программирования является разделение программы на функции и модули. Использование модулей и функций делает программу более понятной и читаемой.

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

Языки программирования: PASCAL (представленный Niklaus Wirth) и C (представленный Dennis Ritchie) следуют этому подходу.

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

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

Языки программирования: FORTRAN (разработанный IBM) и COBOL (разработанный Dr Grace Murray Hopper) следуют этому подходу.

Эти программные конструкции были разработаны в конце 1970-х и 1980-х годов. Все еще были некоторые проблемы с этими языками, хотя они отвечали критериям хорошо структурированных программ, программного обеспечения и т. Д. Они не были так структурированы, как требования в то время. Они кажутся чрезмерно обобщенными и не соотносятся с приложениями реального времени.

Чтобы решить такие проблемы, ООП, объектно-ориентированный подход был разработан в качестве решения.

Объектно-ориентированная модель - Студенческий портал

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

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

Давайте углубимся в общие концепции ООП, которые приведены ниже:

Что такое класс и объект? Это основная концепция ООП; расширенная концепция структуры, используемой в C. Это абстрактный и определенный пользователем тип данных. Он состоит из нескольких переменных и функций.

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

  • Class car {
  •     int car_id;
  •     char colour[4];
  •     float engine_no;
  •     double distance;
  •     void distance_travelled();
  •     float petrol_used();
  •     char music_player();
  •     void display();
  • }

Здесь класс car имеет свойства car_id, color, engine_no и distance.

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

Также есть несколько методов, таких как distance_travelled (), petrol_used (), music_player () и display (). В приведенном ниже коде автомобиль является классом, а c1 является объектом автомобиля.

  1. #include
  2. using namespace std;
  3. class car {
  4. public:
  5.     int car_id;
  6.     double distance;
  7.     void distance_travelled();
  8.     void display(int a, int b)
  9.     {
  10.         cout

Источник: http://espressocode.top/oops-object-oriented-design/

Объектно-ориентированная модель

Объектно-ориентированная база данных состоит из объектов, каждый из которых должен принадлежать к определенному классу, то есть каждый объект – экземпляр класса.

Структура и поведение объектов в объектной среде полностью определяется его классом. Класс, в свою очередь, является коллекцией объектов, при этом структура и поведение объектов одного класса одинаковы.

Заметим, что понятия «объект» и «класс» совпадают с теми же понятиями объектно-ориентированного программирования.

Создание объектной модели начинается с классификации – выявлении объектов с аналогичными свойствами и поведением и объединении их в классы. Однако, некоторые их свойства и методы различны. В этом случае производят генерализацию и специализацию.

Генерализация выявляет классы объектов с аналогичными свойствами и образует на основе этих свойств абстрактный суперкласс.

Например, в базе данных, содержащей описание геометрических фигур, можно начать проектирование с выделения классов: треугольников, прямоугольников, окружностей, – а затем образовать из них абстрактный суперкласс Фигуры, состоящий из свойств, общих для всех фигур.

Специализация – процесс обратный генерализации. При использовании этих процессов создается иерархия классов. Иерархии указывают цепочку наследования.

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

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

Раздел 10. Проектирование реляционных баз данных с использованием универсального языка моделирования UML.

Тема 10.1. Основные понятия диаграмм классов UML

Унифицированный язык моделирования (UML) является стандартным инструментом для создания «чертежей» программного обеспечения. С помощью UML можно визуализировать, специфицировать, конструировать и документировать программные системы.

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

Несмотря на обилие выразительных возможностей, этот язык прост для понимания и использования.

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

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

  1. В UML выделяют девять типов диаграмм:
  2. — диаграммы классов;
  3. — диаграммы объектов;
  4. — диаграммы прецедентов;
  5. — диаграммы последовательностей;
  6. — диаграммы кооперации;
  7. — диаграммы состояний;
  8. — диаграммы действий;
  9. — диаграммы компонентов;
  10. — диаграммы развертывания.

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

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

Диаграммы классов, которые включают активные классы, соответствуют статическому виду системы с точки зрения процессов.

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

На диаграмме прецедентов представлены прецеденты и актеры (участники системы, выполняющие определённые функции), а также отношения между ними. Диаграммы прецедентов относятся к статическому виду системы с точки зрения прецедентов использования. Они особенно важны при организации и моделировании поведения системы.

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

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

Эти диаграммы могут быть преобразованы друг в друга.

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

Диаграмма деятельности ‑ это частный случай диаграммы состояний; на ней представлены переходы потока управления от одной деятельности к другой внутри системы. Диаграммы деятельности относятся к динамическому виду системы; они наиболее важны при моделировании ее функционирования и отражают поток управления между объектами.

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

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

Тема 10.2. Ограничения и язык OCL

Как уже отмечалось, в диаграммах классов могут указываться ограничения целостности, которые должны поддерживаться в проектируемой БД. В UML допускаются два способа определения ограничений: на естественном языке и на языке OCL. Пример: диаграмма классов Студент и Университет с ограничением, выраженным на естественном языке.

Читайте также:  Порядок оценки существенности в аудите - студенческий портал

Объектно-ориентированная модель - Студенческий портал

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

Более точный и лаконичный способ формулировки ограничений обеспечивает язык OCL (Object Constraints Language).

Язык OCL предназначен, главным образом, для определения ограничений целостности данных, соответствующих модели, которая представлена в терминах диаграммы классов UML.

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

  • Примеры ограничений.
  • Рассмотрим БД, состоящую из таблиц
  • Отдел(Номер_отдела, Название)
  • Служащий(Номер_отдела, Должность, Возраст)
  • 1) Пусть в таблице Служащий значения атрибута Возраст должны быть больше 18 и меньше 70 лет. Тогда это ограничение описывается на языке OCL следующим образом:
  • context Служащий inv:

self.возраст > 18 and self.возраст < 70

Условие инварианта накладывает требуемое ограничение на значения атрибута Возраст, определенного в классе Служащий.

В условном выражении инварианта ключевое слово self обозначает текущий объект класса-контекста инварианта.

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

  1. 2) Пусть в каждом отделе должен быть ровно один начальник.
  2. context Отдел inv:
  3. self.служащий  select (должность = «начальник отдела»)  size () = 1

Тема 10.3. Пример разработки структуры и функционала БД

  • В качестве примера рассмотрим базу данных «Библиотека». Основные классы (сущности) для построения диаграммы классов:
  • Читатель(Номер_билета, Фамилия, Имя, Отчество, Адрес, Телефон)
  • Каталог(Шифр_книги, Название, Авторы, Издательство, Год)
  • Книга(Инвентарный_номер, Шифр_книги)
  • Выдача_книг(Номер_записи, Инвентарный_номер, Номер_билета, Дата_выдачи, Дата_возврата, Отметка_о_возврате)
  • Основные процессы для построения диаграммы действий:
  • — регистрация читателя (добавление записи в таблицу Читатель);
  • — поиск книг (выполнение поискового запроса);
  • — выдача книг (добавление записи в таблицу Выдача_книг);
  • — возврат книг (изменение записи в таблице Выдача_книг);
  • — выдача предупреждений о нарушениях срока возврата книг (выполнение поискового запроса);
  • — списание книг (удаление записей из таблиц Книга, Каталог);
  • — статистический анализ деятельности библиотеки (выполнение статистического запроса).

Дата добавления: 2018-04-15; просмотров: 78;

Источник: https://studopedia.net/4_37040_ob-ektno-orientirovannaya-model.html

Введение в объектно-ориентированные базы данных

Объектно-ориентированные базы данных – базы данных, в которых информация представлена в виде объектов, как в объектно-ориентированных языках программирования. Применять или не применять объектно-ориентированные системы управления базами данных (ООСУБД) в реальных проектах сегодня? В каких случаях их применять, а в каких нет?

Вот преимущества использования ООСУБД:

  • Отсутствует проблема несоответствия модели данных в приложении и БД (impedance mismatch). Все данные сохраняются в БД в том же виде, что и в модели приложения.
  • Не требуется отдельно поддерживать модель данных на стороне СУБД.
  • Все объекты на уровне источника данных строго типизированы. Больше никаких строковых имен колонок! Рефакторинг объектно-ориентированной базы данных и работающего с ней кода теперь автоматизированный, а не однообразный и скучный процесс.

Интересно? Тогда стоит попробовать!

В статье описано все, что требуется для начала работы с ООСУБД db4o.

Установка db4o

На сегодняшний день db4o – одна из самых популярных объектно-ориентированных систем управления базами данных.

Для начала скачиваем дистрибутив последней версии с сайта db4o (есть версии для Java, .NET 2.0, 3.5). На момент написания статьи последняя версия – 7.9.

В дистрибутив также входит Object Manager Enterprise (OME) – полезный плагин для IDE (Eclipse, Visual Studio), который позволяет работать с базой данных автономно. В последнюю продуктивную поставку (на данный момент — 7.

4) OME не входит, поэтому для ознакомления c ООСУБД рекомендуется версия 7.9.

Далее в статье для примеров будет использоваться язык C#. Для Java примеры аналогичны, за исключением раздела про LINQ, где необходимым условием является использование .NET 3.5. После установки db4o в соответствующем месте можно найти отличный tutorial, входящий в комплект. Именно к нему я рекомендую обратиться после прочтения данной статьи, если сама тема покажется вам интересной. Отмечаю, что все ПО для работы с db4o и сама СУБД бесплатны для некоммерческого использования.

Cоединение с БД

Для проведения экспериментов над db4o создаем в нашей IDE проект любого типа, например, консольное приложение и добавляем ссылки на сборки (пакеты) db4o: Db4objects.Db4o.dll и Db4objects.Db4o.Linq.dll (если требуется).

Чтобы выполнять какие-либо действия над объектной базой в приложении, первым делом необходимо получить объект типа IObjectContainer.

Это фасад к базе данных: через него выполняются запросы к БД на выборку, сохранение, добавление и удаление данных.

Способ получения объекта зависит от типа соединения с базой данных. Самый простой способ – база данных размещается в локальном файле, к которому приложение получает доступ напрямую. Делается это так:// получаем доступ к файлу БД IObjectContainer db = Db4oFactory.OpenFile(filename);

  • try
  •     // работаем с ООБД
  • finally
  •     // закрываем файл, освобождаем ресурсы
  • }

{ } {     db.Close();

* This source code was highlighted with Source Code Highlighter.

Файл базы данных в этом случае открывается в эксклюзивном режиме и, следовательно, возникают трудности при реализации многопользовательских приложений. Однако такое решение отлично подходит для однопользовательских stand-alone приложений, которые имеют сложную модель данных и которым необходимо сохранять эти данные между запусками приложения. Пример, САПР-приложения.

Следующий способ. Для поддержки многопользовательского режима, то есть возможности существования нескольких IObjectContainer для одной базы данных одновременно, следует использовать клиент-серверную архитектуру. В случае, когда клиент и сервер работают в рамках одного приложения, это делается так:

// создаем сервер IObjectServer server = Db4oFactory.OpenServer(filename, 0);

  1. try
  2.     // подключаем клиентов
  3.     // работаем с ООБД через экземпляры IObjectContainer
  4. finally
  5.     // закрываем файл, освобождаем ресурсы сервера
  6. }

{     IObjectContainer client = server.OpenClient();     IObjectContainer client2 = server.OpenClient();     client.Close();     client2.Close(); } {     server.Close();

* This source code was highlighted with Source Code Highlighter.

В данном случае при создании сервера все равно приходится указывать файл базы данных. Это необходимо делать для всех типов подключения к БД — привязка к файлу остается всегда (один файл — одна БД). Кстати, такой файл создается автоматически по первому требованию, если не был создан до этого.

Второй параметр функции OpenServer – номер порта, равный 0, означает, что сервер будет доступен только локальным клиентам, создаваемым с помощью server.OpenClient().

Приведенный пример искусственный. В реальном приложении клиенты, скорее всего, будут открываться в отдельных потоках. И последний вариант – расширение предыдущего для случая удаленных клиентов.// создаем сервер IObjectServer server = Db4oFactory.OpenServer(filename, serverPort); server.GrantAccess(serverUser, serverPassword);

  • try
  •     IObjectContainer client = Db4oFactory.OpenClient(«localhost», serverPort,
  •     // работаем с ООБД
  • finally
  • }

{                                                      serverUser, serverPassword);     client.Close(); } {     server.Close();

* This source code was highlighted with Source Code Highlighter.

Этот вариант отличается от предыдущего следующим.

  • Указывается реальное значение порта, который будет прослушивать сервер (используется TCP/IP) при вызове OpenServer.
  • Указываются авторизационные данные для доступа к БД.
  • Клиент создается с использованием Db4oFactory.OpenClient и, таким образом, это может происходить не только в другом потоке, но и совершенно в другом приложении, запущенном на удаленной машине.

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

Работа с данными

Пусть где-то в нашем приложении объявлен класс User с полями Login, Password и Age, а db – это объект типа IObjectContainer (тот, что мы получили в прошлом разделе).

Сохранение объекта (INSERT)

User user1 = new User(«Vasya», «123456», 25); db.Store(user1);

* This source code was highlighted with Source Code Highlighter.

Это всё! Не требуется заранее или вручную задавать, какие объекты мы можем сохранять в БД, структуру этих объектов или что-либо ещё. При сохранении первого объекта ООСУБД сделает всю работу за нас.

Запросы к данным (SELECT)

Существует несколько способов выполнить запрос к данным, сохраненным в базе данных.

Применение естественных запросов (Native Queries, NQ) – гибкий, мощный и удобный метод выполнения запросов над данными в ООБД.IList result = db.Query(usr => usr.

Age >= 18                                         && usr.Login.StartsWith(«V»));

* This source code was highlighted with Source Code Highlighter.

Здесь делается запрос к объектам класса User, причем всё, что только можно, в данном примере строго типизировано. Объекты фильтруются таким образом, чтобы удовлетворять условию: возраст пользователя больше или равен 18 и имя пользователя начинается с заглавной буквы «V». Вместо лямбда-выражения функции Query можно передавать делегаты или объекты типа Predicate. Predicate — интерфейс, содержащий единственную функцию Match, принимающую параметр типа T и возвращающую bool. Query вернет те объекты, для которых Match возвращает true. Концепция ООБД отлично ложиться на идею использования интегрированных в язык запросов (LINQ). Перепишем предыдущий запрос с использованием LINQ.IEnumerable result = from User usr in db                           where usr.Age >= 18 && usr.Login.StartsWith(«V»)                           select usr;

* This source code was highlighted with Source Code Highlighter.

Запрос опять же строго типизирован и легко поддается рефакторингу. Существуют и другие методы выполнения запросов, кроме NQ и LINQ.

  • Запросы по образцу (query by example). Самый простой, но недостаточно мощный способ. Выборка данных осуществляется на основе сопоставления с заранее подготовленным экземпляром объекта — образцом. Результат-выборка не является строго типизированной. Сложно представить ситуации, когда этот метод может оказаться полезным.
  • SODA. Низкоуровневый язык запросов, с которым работает db4o. Запросы, использующие синтаксис SODA, не безопасны с точки зрения типов, не строго типизированы, занимают много места, но зато максимально гибки и позволяют отточить производительность приложения там, где это требуется.

Обновление объектов (UPDATE)

Перед тем как обновить объект, извлечем его из БД, затем изменим его и сохраним обратно.User usr = db.Query(usr => usr.Login == «Vasya»)[0]; usr.SetPassword(«111111»); db.Store(usr);

* This source code was highlighted with Source Code Highlighter.

Удаление объектов (DELETE)

Удаление объектов происходит аналогично:User usr = db.Query(usr => usr.Login == «Vasya»)[0]; db.Delete(usr);

* This source code was highlighted with Source Code Highlighter.

Составные объекты

До этого момента мы рассматривали, как работать с достаточно простыми объектами User, которые содержали только поля элементарных типов (string и int). Однако объекты могут быть составными и ссылаться на другие объекты. Например, в классе User может быть объявлено поле friends (друзья пользователя): public class User {

    // …

    IList friends = new List(); }

* This source code was highlighted with Source Code Highlighter.

Читайте также:  Издержки производства - студенческий портал

Все операции с таким классом производятся также, как и раньше – составное поле корректно сохраняется в БД, однако есть некоторые особенности.

Допустим, мы пытаемся загрузить из БД объект одного конкретного пользователя (User), как это делалось в прошлом разделе. Если загружен сам пользователь, то должны загрузиться и его друзья, дальше – друзья его друзей, и так далее.

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

Для некоторых ситуаций это много, для других – мало. Существует способ настроить этот параметр, называемый глубиной активации (activation depth).

// глубина активации глобально для всех классов db.Ext().Configure().ActivationDepth(2);

// глубина активации для класса User

db.Ext().Configure().ObjectClass(typeof(User)).MinimumActivationDepth(3); db.Ext().Configure().ObjectClass(typeof(User)).MaximumActivationDepth(4);

// каскадная активация для объектов User (нет ограничения на глубину)

db.Ext().Configure().ObjectClass(typeof(User)).CascadeOnActivate(true);

* This source code was highlighted with Source Code Highlighter.

Здесь приведены примеры, устанавливающие глубину активации как для всех сразу, так и для отдельного класса. Функция Ext() возвращает расширенный объект IExtObjectContainer для доступа к продвинутым функциям вроде настроек конфигурации базы данных. Это сделано для удобства, чтобы не засорять основной интерфейс IObjectContainer.

В случае, когда запрос уже отработал, но каких-либо данных не хватает, то есть не все нужные данные были активированы (загружены в память), можно использовать метод Activate, применительно к отдельному хранимому объекту:

// первый параметр – активируемый объект, второй – глубина активации db.Activate(usr, 5);

* This source code was highlighted with Source Code Highlighter.

Во многом похожая проблема возникает при сохранении составных объектов. По умолчанию сохраняются только поля самого объекта, но не объектов, на которые он ссылается. То есть, глубина обновления (update depth) по умолчанию равна 1. Изменить её можно следующим образом: // глубина обновления глобально для всех классов db.Ext().Configure().UpdateDepth(2);

// глубина обновления для класса User

db.Ext().Configure().ObjectClass(typeof(User)).UpdateDepth(3);

// каскадное обновление для объектов User (нет ограничений на вложенность)

db.Ext().Configure().ObjectClass(typeof(User)).CascadeOnUpdate(true);

* This source code was highlighted with Source Code Highlighter.

В случае удаления объекта, по умолчанию также не происходит каскадного удаления: объекты, на которые ссылался удаленный объект, остаются. Настраивать поведение СУБД в случае удаления объектов можно следующим образом: // каскадное удаление (нет ограничений на вложенность) db.Ext().Configure().ObjectClass(typeof(User)).CascadeOnDelete(true);

* This source code was highlighted with Source Code Highlighter.

Понятия «глубины удаления» не предусмотрено.

Транзакции

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

Для более гибкого управления транзакциями в интерфейсе IObjectContainer присутствуют два метода:

  • Commit(). Явное завершение транзакции (commit) с записью всех изменений в БД.
  • Rollback(). Откат транзакции – изменения произошедшие с момента открытия транзакции (контейнера) не будут зафиксированы в БД.

Уровень изоляции транзакций, принятый в db4o — read committed.

Заключение

Цель данной статьи — показать, что имеется очень мощная альтернатива существующим подходам к разработке с использованием реляционных СУБД. Сам по себе подход, использующий объектные базы данных, очень современен – это СУБД, которая не отстает от основных тенденций, наблюдаемых в развитии языков программирования, таких как Java и C#.

В статье достаточно материала, чтобы начать работать с ООСУБД, создавая реальные приложения. Однако многие вопросы здесь затронуты не были, например, вопросы, связанные с производительностью и разработкой веб-приложений.

В любом случае, если и не начать применять объектные СУБД на практике уже сегодня, то стоит хотя бы задуматься, не лучшее ли это решение для вашего проекта?

Источник: https://habr.com/post/56399/

Модели контента: реляционная модель, объектно-ориентированная модель, онтологическая модель

Библиографическая запись: Модели контента: реляционная модель, объектно-ориентированная модель, онтологическая модель // Myfilology.ru – информационный филологический ресурс : [сайт]. – 2017-12-17 19:33:24. – URL: https://myfilology.ru//192/modeli-kontenta-relyaczionnaya-model-obektno-orientirovannaya-model-ontologicheskaya-model/ (дата обращения: 20.03.2020)

Модели контента: реляционная модель, объектно-ориентированная модель, онтологическая модель

Контентная модель — это набор правил, которые определяют можно ли использовать некоторый элемент в некотором контенте или нет.

Реляционная модель контента

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

Достоинство реляционной модели данных заключается в простоте, понятности и удобстве физической реализации на ЭВМ.

К основным недостаткам реляционной модели относятся отсутствие стандартных средств идентификации отдельных записей и сложность описания иерархических и сетевых связей

Данная модель представления данных опирается на теорию графов: структура информации представляется в виде узлов с помеченными связями между ними. Фундаментом системы может служить как сетевая, так и традиционная реляционная СУБД, на которую отображена сетевая модель описания данных.

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

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

Объектно-ориентированная модель контента

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

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

Определив один класс, можно создать множество его представителей (контент объектов).

В CMS-системах данные обычно хранятся в реляционной или объектной базе данных. В первом случае объектная модель данных отображается на реляционную модель базы данных.

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

Онтологическая модель контента

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

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

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

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

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

Экземпляры

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

Понятия

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

  • Понятие «люди», вложенное понятие «человек». Чем является «человек» — вложенным понятием, или экземпляром (индивидом) — зависит от онтологии.
  • Понятие «индивиды», экземпляр «индивид».

Классы онтологии составляют таксономию — иерархию понятий по отношению вложения.

Атрибуты

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

  • НазваниеАвтомобиль-модели-А
  • Число-дверей: 4
  • Двигатель: {4.0Л, 4.6Л}
  • Коробка-передач: 6-ступенчатая

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

Отношения

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

Предположим, что в онтологии автомобилей присутствует два объекта — автомобиль Автомобиль-модели-А и Автомобиль-модели-Б.

Пусть Автомобиль-модели-Б это модель-наследник Автомобиль-модели-А, тогда отношение между Автомобиль-модели-А и Автомобиль-модели-Б определим как атрибут «isSuccessorOf» со значением «Автомобиль-модели-А» для объекта Автомобиль-модели-Б (следует заметить, что в языках описания онтологий существуют предопределенные отношения наследования).

Специализированные и общие онтологии

Специализированные (предметно-ориентированные) онтологии — это представление какой-либо области знаний или части реального мира. В такой онтологии содержатся специальные для этой области значения терминов. К примеру, слово «поле» в сельском хозяйстве означает участок земли, в физике — один из видов материи, в математике — класс алгебраических систем.

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

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

Разница может появляться из-за особенностей местной культуры, идеологии или вследствие использования другого языка описания. Объединение онтологий выполняют как вручную, так и в полуавтоматическом режиме. В целом это — трудоёмкий, медленный и дорогостоящий процесс. Использование базисной онтологии — единого глоссария — несколько упрощает эту работу.

Есть научные работы по технологиям объединения, но они по большей части теоретические.

Источник: https://myfilology.ru/192/modeli-kontenta-relyaczionnaya-model-obektno-orientirovannaya-model-ontologicheskaya-model/

Объектно-ориентированная система на C

Ниже представлен подробно откомментированный код объектно-ориентированной системы на C. Работающий исходный код можно скачать по адресу: https://gist.github.com/be9/03fc3444dd90d1c78f58

Система взята из книги Object-Oriented Programming With ANSI C (автор Axel-Tobias Schreiner).

Файл new.h

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

// Стандартная преамбула для заголовочного файла, гарантирующая его однократное
// включение
#ifndef __new_h
#define __new_h // Нужно для size_t (беззнаковое целое с размером, соответствующим разрядности
// архитектуры)
#include // Нужно для va_list (тип, на котором основывается работа с переменным
// количеством аргументов у функций)
#include /*
* Базовая структура, в которой хранится информация о классе. Не путать со
* структурой объекта! Для каждого класса существует одна-единственная глобальная
* переменная типа Class.
*/
struct Class { // Размер объекта описываемого класса в байтах size_t size; /*
* Указатель на функцию-конструктор, вызываемую в процессе создания
* объекта. В качестве первого аргумента (self) функция принимает указатель
* на выделенную под объект память (размером size). Второй аргумент —
* указатель на переменную типа va_list, которая «настроена» на первый аргумент
* конструктора. Если конструктор принимает какие-либо аргументы, он должен
* получить их с помощью нужного количества * вызовов va_arg.
*
* Функция-конструктор возвращает указатель, который будет
* являться результатом вызова new. Как правило, она просто вернёт self.
*
* Указатель ctor может быть нулевым, в этом случае никакого
* дополнительного конструирования объекта не производится, а просто
* зануляется выделенная память.
*/ void *(*ctor)(void *self, va_list *app); /*
* Указатель на функцию-деструктор. В качестве аргумента функция принимает
* указатель на объект и осуществляет необходимые операции по очистке:
* закрытие файлов, освобождение дополнительно выделенной памяти и т.д.
*
* Указатель dtor может быть нулевым, в этом случае очистка не
* производится, а просто освобождается выделенная память.
*
* Деструктор должен вернуть тот указатель, который передавался в
* качестве аргумента конструктору (обычно это просто self).
*/ void *(*dtor)(void *self); /*
* Указатель на реализацию виртуальной функции, которая будет вызываться в
* зависимости от реального типа объекта. В данном примере есть всего одна
* виртуальная функция, draw. Если задача требует большего количества
* виртуальных функций, все они должны быть добавлены сюда с соответствующими
* прототипами.
*
* Первый аргумент функции (self) – указатель на объект.
*/ void (*draw)(const void *self);
}; // Функция создания объекта. Первый аргумент — указатель на структуру-описание
// класса (типа Class). Прочие аргументы будут переданы конструктору (ctor).
// Функция возвращает указатель на созданный и проинициализированный объект.
void *new(const void *class, …); // Функция уничтожения объекта. Аргумент item — указатель на объект
// (который был ранее возвращен функцией new). Перед освобождением памяти
// вызывает деструктор dtor (при его наличии).
void delete(void *item); // Виртуальная функция draw. Аргумент self — указатель на объект. В зависимости от
// класса объекта будет вызвана соответствующая реализация draw.
void draw(const void *self); #endif

Читайте также:  Значение царства грибов: систематика и практическая польза

Файл new.c

Реализация функций из new.h

// Для calloc и free
#include // Для assert.h
#include
#include «new.h» // Реализация функции new
void *new(const void *_class, …)
{ // Пребразуем тип переданного указателя. Хотя он и объявлен как void * // (в целях сокрытия данных о классе), мы-то знаем, что это struct Class *. const struct Class *class = _class; // Выделяем память. Стандартная функция calloc обычно используется для // создания массивов. Её первый аргумент — размер массива, второй — размер // ячейки массива. После выделения соответствующего количества памяти // она зануляет эту память и возвращает указатель. void *p = calloc(1, class->size); // Проверка на то, что память выделилась assert(p); // Прописывание класса объекта. Все объекты в системе устроены так, что в самых // первых байтах памяти, выделенной под объект, содержится указатель на // глобальную структуру типа Class, описывающую класс этого объекта. Здесь // этот указатель лежит в переменной class. p как раз указывает на то место, // куда должен лечь class. *(const struct Class **)p = class; // Если задан конструктор… if (class->ctor) { va_list ap; // Инициализируем работу с переменными аргументами. После выполнения // va_start ap будет указывать на следующий аргумент после _class, // то есть первый аргумент, который должен достаться функции-конструктору. va_start(ap, _class); // Вызываем конструктор p = class->ctor(p, &ap); // Очищаем ap va_end(ap); } // Возвращаем указатель на объект return p;
} // Реализация функции delete
void delete(void *self)
{ // Поскольку нам потребуется доступ к описанию класса объекта, // сделаем удобное преобразование типов const struct Class **cp = self; // Проверка деструктора. *cp получает указатель на struct Class, // из которой достаём поле dtor if (self && *cp && (*cp)->dtor) // Если деструктор задан, вызываем его. Он должен вернуть указатель // на исходный блок памяти self = (*cp)->dtor(self); // Освобождаем выделенный блок памяти free(self);
} // Реализация функции draw
void draw(const void *self)
{ // Поскольку нам потребуется доступ к описанию класса объекта, // сделаем удобное преобразование типов const struct Class * const *cp = self; // Проверяем, что объект, описание класса и указатель на реализацию виртуального // метода являются ненулевыми assert(self && *cp && (*cp)->draw); // Вызываем виртуальный метод по указателю (*cp)->draw(self);
}

Файл point.h

Объявление структуры данных и функций для класса Point

// Стандартная преамбула для заголовочного файла, гарантирующая его однократное
// включение
#ifndef __point_h
#define __point_h // Структура объекта класса Point
struct Point { // Указатель на описание структуры класса (см. комментарии внутри функции // new) const void *class; // Координаты точки int x, y;
}; // Невиртуальный метод класса. Смещает точку в 2D-пространстве.
void move(void *_self, int dx, int dy); // Ссылка на указатель на описание класса Point, объявленный в point.c.
extern const void *Point; #endif

Файл point.c

Реализация конструктора и виртуального метода draw, невиртуального метода move,
структура-описание класса.

// Для va_arg
#include
#include
// Для printf
#include
#include «point.h»
// Для struct Class
#include «new.h» // Реализация функции move
void move(void * _self, int dx, int dy)
{ // Функция будет работать для объекта класса Point и объектов производных // классов, поскольку у всех них есть поля x и y, но дополнительного // «интеллекта», зависящего от действительного класса объекта, у неё нет. struct Point *self = _self; // Выполняем смещение self->x += dx; self->y += dy;
} // Реализация конструктора для класса Point. Поскольку конструктор является
// деталью реализации и не будет вызываться извне напрямую (только по
// указателю), он объявлен как static.
static void *Point_ctor(void *_self, va_list *app)
{ // В выделенную память ляжет структура Point struct Point *self = _self; // Достаём 2-й аргумент new и сохраняем в поле x self->x = va_arg(*app, int); // Достаём 3-й аргумент new и сохраняем в поле y self->y = va_arg(*app, int); // Возвращаем указатель на объект return self;
} // Реализация виртуального метода draw для класса Point. Виртуальный метод
// также не предназначен для прямого вызова, поэтому объявляется с ключевым
// словом static.
static void Point_draw(const void *_self)
{ // Мы знаем, что то, что нам передали, это указатель на Point const struct Point *self = _self; // Печать координат printf(«».» at %d,%d
«, self->x, self->y);
} // Описание класса Point. Эта переменная будет находиться в глобальной памяти,
// но будет недоступна извне (static)
static const struct Class _Point = { // Размер структуры данных объекта sizeof(struct Point), // Указатель на функцию-конструктор Point_ctor, // Деструктор отсутствует 0, // Указатель на виртуальную функцию draw Point_draw
}; // Объявление глобального указателя на _Point, который и будет представлять
// собой класс Point для пользователей (служить аргументом для функции new).
const void *Point = &_Point;

Файл circle.h

Объявления для класса Circle

// Стандартная преамбула для заголовочного файла, гарантирующая его однократное
// включение
#ifndef __circle_h
#define __circle_h // Для struct Point
#include «point.h» // Структура объекта класса Circle
struct Circle { // Поскольку Circle наследуется от Point, он содержит все те поля, которые // есть в Point const struct Point _; // Поле, специфичное для Circle – радиус круга int rad;
}; // Ссылка на указатель на описание класса Circle, объявленный в circle.c.
extern const void *Circle; #endif

Файл circle.c

Реализация конструктора и виртуальной функции draw для класса Circle. Описание
класса Circle.

// Для printf
#include
#include «circle.h»
// Для struct Class
#include «new.h» // Объявление конструктора для Circle
static void *Circle_ctor(void *_self, va_list *app) { // Поскольку Circle унаследован от Point, первым делом мы // вызываем конструктор класса Point, передавая ему наши аргументы. // То, что он вернёт, можно преобразовать к указателю на Circle, // потому что выделенная память имеет размер sizeof (struct Circle). struct Circle *self = ((const struct Class *)Point)->ctor(_self, app); // Конструктор Point считал два аргумента и сохранил их в поля x и y. // Мы же считаем третий аргумент и сохраним его в поле rad self->rad = va_arg(*app, int); // Возвращаем указатель на объект return self;
} // Эти два макроопределения удобны для доступа к полям базового класса Point
// Преобразуем p в указатель на struct Point и достаём соответствующее поле
#define x(p) (((const struct Point *)(p)) -> x)
#define y(p) (((const struct Point *)(p)) -> y) // Реализация виртуальной функции draw для класса Circle
static void Circle_draw(const void * _self)
{ // Мы знаем, что то, что нам передали, это указатель на Circle const struct Circle *self = _self; // Выводим поля. Для доступа к полям x и y используются макроопределения, // поскольку мы не можем напрямую написать self->x и self->y // (ведь они объявлены в struct Point, а не в struct Circle) printf(«circle at %d,%d rad %d
«, x(self), y(self), self->rad);
} // Описание класса Circle
static const struct Class _Circle = { // Размер структуры данных объекта sizeof(struct Circle), // Указатель на функцию-конструктор Circle_ctor, // Деструктор отсутствует 0, // Указатель на виртуальную функцию draw Circle_draw
}; // Объявление глобального указателя на _Circle, который и будет представлять
// собой класс Circle для пользователей (служить аргументом для функции new).
const void *Circle = &_Circle;

Файл main.c

Главная программа, которая создаёт и уничтожает объекты классов Point и Circle.

Программа вызывается с аргументами, соответствующими классам (p и c).

// Для Point
#include «point.h»
// Для Circle
#include «circle.h»
// Для new.h
#include «new.h» int main(int argc, char **argv)
{ // Достаём аргументы командной строки по одному while (*++argv) { // Указатель на текущий объект void *p; // Анализируем первый символ switch (**argv) { case 'p': // Создаем объект класса Point p = new(Point, 1, 2); break; case 'c': // Создаем объект класса Circle p = new(Circle, 1, 2, 3); break; default: // Неизвестный аргумент, пропускаем continue; } // Отрисовка начального местоположения объекта draw(p); // Сдвиг объекта move(p, 10, 20); // Отрисовка нового местоположения объекта draw(p); // Уничтожение объекта delete(p); } return 0;
}

Источник: http://oop.afti.ru/materials/3

Ссылка на основную публикацию