Поддержка разработки бизнес приложений на Ada

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

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

Общие требования

Продукт должен иметь следующие возможности:

  • устойчивое хранение состояния объектов в различных хранилищах (например основанных на реляционных базах данных или BerkleyDB);
  • поддержка локальных и распределённых транзакций;
  • удалённый доступ к объектам по протоколам CORBA/IIOP;
  • защита информации (идентификация, аутентификация, аудит, шифрование и подпись, резервное копировани и восстановление);
  • реплицирование данных и возможность горячей замены;
  • поддержка темпоральных данных.

Минимальные требования к используемым как хранилища базам данных:

  • поддержка локальных транзакций (ACID?);
  • резервное копирование и восстановление;
  • реплицирование данных (hot backup and standby).

Желательные требования к используемым как хранилища базам данных:

  • поддержка распределённых транзакций (XA?).

Архитектура

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

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

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

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

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

API версии 0.2 (действующее)

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

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

Интерфейсный тип устойчивого объекта

--  Пакет объявляет базовый интерфейсный тип для объектов с устойчивым
--  хранением состояния.
with PO.Persistent_Object_Identifiers;

package PO.Persistent_Entities is

   pragma Pure;

   type Persistent_Entity is limited interface;

   not overriding
   function Get_Object_Identifier
    (Self : not null access constant Persistent_Entity)
       return PO.Persistent_Object_Identifiers.Persistent_Object_Identifier
         is abstract;

end PO.Persistent_Entities;

Абстрактный тэговый тип устойчивого объекта

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

package PO.Persistent_Entities.Implementations is

   pragma Pure;

   type Persistent_Entity_Implementation is
     abstract limited new Persistent_Entity with private;

   not overriding
   procedure Post_Create_Hook
    (Self : not null access Persistent_Entity_Implementation)
       is null;
   --  Вызывается после создания нового экземпляра объекта.

   not overriding
   procedure Pre_Load_Hook
    (Self : not null access Persistent_Entity_Implementation)
       is null;
   --  Вызывается перед началом загрузки состояния.

   not overriding
   procedure Post_Load_Hook
    (Self : not null access Persistent_Entity_Implementation)
       is null;
   --  Вызывается по окончании загрузки состояния.

   not overriding
   procedure Pre_Save_Hook
    (Self : not null access Persistent_Entity_Implementation)
       is null;
   --  Вызывается перед началом сохранения состояния.

   not overriding
   procedure Post_Save_Hook
    (Self : not null access Persistent_Entity_Implementation)
       is null;
   --  Вызывается после окончания сохранения состояния.

   not overriding
   procedure Pre_Destroy
    (Self : not null access Persistent_Entity_Implementation)
       is null;
   --  Вызывается перед уничтожением экземпляра объекта.

private

   ...

end PO.Persistent_Entities.Implementations;

Интерфейсный тип ссылки на объект

--  Пакет описывает базовый интерфейсный тип для всех классов ссылок.

package PO.References is

   pragma Pure;

   type Reference is limited interface;

   function To_String (Item : access Reference'Class) return String;
   --  Возвращет текстовое представление ссылки.

   function To_Reference (Item : in String) return access Reference'Class;
   --  Формирует ссылку из текстового представления.

end PO.References;

API версии 0.1 (устаревшее)

Библиотека предоставляет два основных пакета для построения объектов предоставляющих удалённый доступ: PO.Entities, PO.Entities.Implementations. Для создания устойчивых объектов библиотека предоставляет два дополнительных пакета: PO.Persistent_Entities и PO.Persistent_Entities.Implementations.

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

Примечание: Фабрики объектов представляют из себя точно такие же объекты (?) и порождаются от тех же типов - не верно, фабрики должны либо порождаться от отдельных типов, либо от некоторых подклассов.

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

Вспомогательные пакеты включают: PO.Entities.Client_Stubs, PO.Object_Adapters, PO.Persistent_Object_Adapters.

Пакет PO.Entities

Пакет PO.Entities объявляет базовый интерфейс, поддерживаемый любым объектом с удалённым доступом.

--  Такет описывает базовый интерфейсный тип для всех классов библиотеки,
--  обеспечивающих удалённый доступ.

package PO.Entities is

   pragma Pure;

   type Entity is limited interface;

end PO.Entities;

Пакет PO.Entities.Implementations

Пакет PO.Entities.Implementations объявляет базовый тэговый тип для реализаций объектов, поддерживающих удалённый доступ. Он так же реализует интерфейс Entity.

--  Пакет объявляет абстрактный тэговый тип для построения реализации классов
--  объектов.

package PO.Entities.Implementations is

   pragma Pure;

   type Entity_Implementation is abstract limited new Entity with null record;

end PO.Entities.Implementations;

Пакет PO.Persistent_Entities

Пакет PO.Persistent_Entities объявляет базовый интерфейсный тип для устойчивых объектов.

--  Пакет объявляет базовый интерфейсный тип для объектов с устойчивым
--  хранением состояния. Все объекты с устойчивым хранением состояния
--  поддерживают интерфейс Entity, и таким образом являются удалённо
--  доступными.
with PO.Entities;
with PO.Persistent_Object_Identifiers;

package PO.Persistent_Entities is

   pragma Pure;

   type Persistent_Entity is limited interface and PO.Entities.Entity;

   not overriding
   function Get_Object_Identifier
    (Self : not null access constant Persistent_Entity)
       return PO.Persistent_Object_Identifiers.Persistent_Object_Identifier
         is abstract;

end PO.Persistent_Entities;

Пакет PO.Persistent_Entities.Implementations

Пакет PO.Persistent_Entities.Implementations объявляет базовый абстрактный тэговый тип для построения реализаций устойчивых объектов.

--  Пакет содержит объявление абстрактного тэгового типа для всех реализаций
--  устойчивых объектов.
with PO.Entities.Implementations;

package PO.Persistent_Entities.Implementations is

   pragma Pure;

   type Persistent_Entity_Implementation is
     abstract new PO.Entities.Implementations.Entity_Implementation
     and Persistent_Entity with private;

   not overriding
   procedure Post_Create_Hook
    (Self : not null access Persistent_Entity_Implementation)
       is null;
   --  Вызывается после создания нового экземпляра объекта.

   not overriding
   procedure Pre_Load_Hook
    (Self : not null access Persistent_Entity_Implementation)
       is null;
   --  Вызывается перед началом загрузки состояния.

   not overriding
   procedure Post_Load_Hook
    (Self : not null access Persistent_Entity_Implementation)
       is null;
   --  Вызывается по окончании загрузки состояния.

   not overriding
   procedure Pre_Save_Hook
    (Self : not null access Persistent_Entity_Implementation)
       is null;
   --  Вызывается перед началом сохранения состояния.

   not overriding
   procedure Post_Save_Hook
    (Self : not null access Persistent_Entity_Implementation)
       is null;
   --  Вызывается после окончания сохранения состояния.

   not overriding
   procedure Pre_Destroy
    (Self : not null access Persistent_Entity_Implementation)
       is null;
   --  Вызывается перед уничтожением экземпляра объекта.

private

   type Persistent_Entity_Implementation is
     abstract new PO.Entities.Implementations.Entity_Implementation
     and Persistent_Entity with
   record
      Object_Identifier :
        PO.Persistent_Object_Identifiers.Persistent_Object_Identifier;
   end record;

   overriding
   function Get_Object_Identifier
    (Self : not null access constant Persistent_Entity_Implementation)
       return PO.Persistent_Object_Identifiers.Persistent_Object_Identifier;

end PO.Persistent_Entities.Implementations;

Внутренний пакет PO.Entities.Client_Stubs

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

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

package PO.Entities.Client_Stubs is

   pragma Pure;

   type Entity_Client_Stub is abstract limited new Entity with private;

private

   type Entity_Client_Stub is abstract limited new Entity with null record;

end PO.Entities.Client_Stubs;

Пакет PO.Object_Adapters

Пакет PO.Object_Adapters объявляет тэговый тип для представления объектного адаптера - внутреннего механизма для управления объектами. Объявленный объектный адаптер используется только для объектов не реализующих устойчивое хранение.

--  Пакет содержит описание объектного адаптера - специального класса,
--  обеспечивающего создание ссылок на объекты и управление объектами.
with PO.Entities;

package PO.Object_Adapters is

   pragma Pure;

   type Object_Adapter is tagged limited private;

   not overriding
   function Create (Self  : not null access Object_Adapter;
                    Class : in Wide_String)
     return not null access PO.Entities.Entity'Class;

private

   type Object_Adapter is tagged limited null record;

end PO.Object_Adapters;

Пакет PO.Persistent_Object_Adapters

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

--  Пакет объявляет тэговый тип объектного адаптера объектов с устойчивым
--  состоянием.
with PO.Object_Adapters;

package PO.Persistent_Object_Adapters is

   type Persistent_Object_Adapter is
     new PO.Object_Adapters.Object_Adapter with null record;

end PO.Persistent_Object_Adapters;

Параметры качества обслуживания

Для каждого объекта при создании может быть задано несколько параметров качества обслуживания:

  • поддержка транзакций: с поддержкой транзакций, без поддержки транзакций;
  • поддержка темпоральности: без поддержки темпоральности; поддержка темпоральности; поддержка битемпоральности.

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

Пример использования

Для создания своего хранимого объекта необходимо:

  • объявить интерфейсный тип и операции над этим типом;
  • объявить тэговый тип реализации, прямо или косвенно порождённый от тэгового типа Entity_Implementation и реализующий интерфейсный тип объекта;
  • сгенерировать реализацию тэгового типа заглушки клиента и вспомогательных подпрограмм чтения/сохранения состояния объекта.
with Entities;

package My_Entities is

   type My_Entity is limited interface and Entities.Entity;

   not overriding
   function Get_Number (Self : not null access constant My_Entity)
     return Integer
       is abstract;

   not overriding
   procedure Set_Number (Self : not null access My_Entity;
                         To   : in Integer)
     is abstract;

end My_Entities;
with Entities.Implementations;

package My_Entities.Implementations is

   type My_Entity_Implementation is
     new Entities.Implementations.Entity_Implementation
       and My_Entity with private;

private

   ...

end My_Entities.Implementations;

Дополнительные материалы

Подсказка Vlad:

На эту тему дофига материалов. Например hybernating в среде java. Вообще все что касается object to rdbms mapping

http://www.hibernate.org/

Темпоральные базы данных (время имеет занчение!)

Richard T. Snodgrass, Time-Oriented Database Applications in SQL

What are Temporal Databases?