BOLD - инструмент реализации MDA в Delphi


         

Основные классы


У внутренних классов предком является класс TObject, а у внешних — класс TComponent.

Фрагмент иерархии внутренних классов представлен на рис. 2.

Кратко опишем некоторые из них.

TBoldMemoryManagedObject ? класс-родоначальник этой иерархии классов. Его появление обусловлено тем, что Borland MDA имеет собственный менеджер памяти.

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

Класс TBoldSubscribableObject предоставляет очень важный для Borland MDA механизм подписки на события. Практически любые компоненты Borland MDA, в том числе визуальные, способны выступать в качестве источников определенных событий, на которые можно «подписаться», а по их наступлении автоматически исполнить заранее заданные реакции — обработчики событий. Механизм подписки эффективно используется самой средой Borland MDA, в частности при работе с вычисляемыми (derived) атрибутами и ассоциациями. Этот механизм также доступен и разработчику, предоставляя уникальные возможности по управлению работой приложения в событийно-организованной программной системе.

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

Класс TBoldSystem представляет объектное пространство в целом, то есть обладает информацией обо всех экземплярах элементов модели приложения.

Класс TBoldObject представляет объект объектного пространства Borland MDA. При генерации кода все пользовательские классы являются потомками TBoldObject. Все объекты в объектном пространстве также являются потомками этого класса либо дочерними по отношению к его потомкам.

Все члены, входящие в состав любого объекта Borland MDA (например, атрибуты), принадлежат к классу TBoldMember. Однако этот класс служит и для других целей, а также имеет самостоятельное значение, порождая, например, такой класс, как TBoldList, который, в свою очередь, является родителем важного класса TBoldObjectList. Как следует из названия, этот класс служит для представления списка объектов.

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

Вспомним теперь наш пример с приложением — библиотечным каталогом из 4-й части данного цикла — и поставим следующую задачу: программно, в процессе работы приложения, получить фамилию первого автора в каталоге. Напомним, что в нашей модели присутствует класс с названием (Expression Name) «Avtor». Для доступа к списку всех объектов класса «Avtor» используем следующее выражение:



BoldSystemHandle1.System.ClassByExpressionName[‘Avtor’];

Здесь BoldSystemHandle1 ? компонент Borland MDA, отвечающий за управление объектным пространством, System ? свойство этого компонента типа TBoldSystem (см. выше и рис. 1), ClassByExpressionName ? метод класса TBoldSystem, возвращающий выражение типа TBoldObjectList (в данном случае ? список всех объектов-экземпляров класса «Avtor» модели).

Класс TBoldObjectList имеет свойство BoldObjects[i] — типа TBoldObject, указывает на объект в списке с порядковым номером i (при этом первый объект в списке имеет номер 0). В свою очередь, класс TBoldObject обладает свойством BoldMemberByExpressionName[‘имя_члена’], позволяющим получить доступ к заданному атрибуту (члену класса). Теперь мы можем сформировать полное выражение-оператор для решения нашей задачи:

BoldSystemHandle1.System.ClassByExpressionName[‘avtor’].BoldObjects[0].BoldMemberByExpressionName[‘fio’].AsString;

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

Таким образом, рассмотренный пример дает возможность сделать следующие важные выводы:

• каждому классу модели соответствует свой объект-экземпляр класса TBoldObjectList объектного пространства;

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

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

Возвращаясь к иерархии внутренних классов (см. рис. 2), стоит обратить внимание на класс TBoldAttribute, являющийся родительским классом (суперклассом) для нескольких классов, представляющих атрибуты различных типов — строковых (TBAString), даты (TBADate), битовых массивов BLOB (TBABlob) и т.д. Таким образом, мы видим, что Borland MDA имеет свои типы данных — аналоги стандартных Delphi-типов. И это не случайно, поскольку Borland MDA представляет собой своего рода систему в системе, то есть самостоятельную программную систему, функционирующую в рамках определенной операционной системы (в настоящее время Windows) и обладающую собственным менеджером памяти, собственным развитым механизмом генерации и обработки событий, а также другими подобными свойствами.

При желании разработчик может создать и зарегистрировать новый MDA-тип данных, воспользовавшись мастером создания атрибутов (в меню Delphi выбрать Bold > Attribute Wizard…).

Теперь кратко рассмотрим иерархию внешних классов (рис. 3).

Все внешние классы имеют в качестве родительского класс TComponent. Это, естественно, означает, что большинство таких классов мы увидим на палитре компонентов среды разработки Delphi. Если внутренние классы можно рассматривать как своего рода «скелет», поддерживающий сложный «организм» объектного пространства, то внешние классы скорее являются своеобразными «адаптерами-переходниками» к уровню представления и уровню данных, а также основными инструментами разработчика Borland MDA-приложений. Уровни представления и данных мы рассмотрим в последующих частях статьи более детально. Сейчас лишь обратим внимание на тот факт, что большинство внешних классов содержит термин «Handle», значение которого в контексте нашего рассмотрения целесообразно перевести как «описатель».



Содержание раздела