Классика баз данных - статьи

       

Моделирование с помощью родовой структуры


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

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

Рис. 7. Графическое представление родовой структуры

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

Предположим, что мы должны моделировать "служащих" (employee) некоторой компании. Допустим также, что в этой компании в некоторый момент времени имеется три различных типа служащих – водители грузовиков (trucker), секретари (secretary) и инженеры (engineer). Должна поддерживаться информация о каждом отдельном служащем – хотя в зависимости от типа служащих необходимы различные виды информации. Кроме того, должна поддерживаться информация о каждом родовом типе служащих.

Более конкретно, предположим, что атрибуты "идентификационный номер служащего" (employee ID#), "фамилия" (name), "возраст" (age) и "тип служащего" (employee type) являются важными для всех отдельных служащих.
Все эти компоненты – примитивны. Полученная модель представлена на рис.10.



Рис. 10. Декомпозиция объекта "employee" в плоскости агрегации

Теперь мы можем продолжить разрабатывать модель, декомпозируя любой объект (который еще не был декомпозирован) в любой плоскости. Поскольку для нас не представляют интерес какие-либо подтипы "employee type", этот объект не декомпозируется в плоскости обобщения. По подобным же причинам мы не декомпозируем объекты "trucker", "secretary" и "engineer" в плоскости обобщения. Однако каждый из этих трех объектов должен быть декомпозирован на (примитивные) объекты в плоскости агрегации. Эти декомпозиции включены на рис.11. Чтобы избежать загромождения рисунка, мы не провели до конца линии, связывающие каждый объект "employee ID#", "name" и "age" с каждым из объектов "trucker", "secretary" и "engineer". В заключение мы можем выбрать для каждого объекта селекторы и ключи. И тогда получается реляционная модель, представленная на рис. 11.





Рис. 11. Реляционная модель для объекта "employee"

Определения отношений "employee" и "employee type" даются на рис.12. Заметим, что в отношении "employee type" содержатся детальные сведения о "trucker", "secretary" и "engineer", когда они полагаются родовыми объектами. Отношение "employee" отсылает к этим детальным сведениям через домен образов (т.е. домен с селектором "TN"). Это позволяет для каждого отдельного служащего ссылаться на все родовые свойства подкласса служащих, к которому он относится.

var employee: generic

TN = (trucker, txoretary, engineer) of

aggregate [E#] E#: employee ID#; N: name; А: age; TN: key employee-type end

var employee-type: generic of

aggregate [TN] TN: typename; N: size; А: vacancies; TN: agency end

Рис. 12. Определение для объектов "employee" и "employee-type" с



В общем случае отношение R может иметь в плоскости обобщения несколько принадлежаших ему кластеров. Для каждого кластера C будет существовать соответствующее отношение, на которое ссылается R в плоскости агрегации. Это отношение будет описывать атрибуты (если они имеются) родовых объектов в C. Можно следующим образом резюмировать это общее свойство реляционных моделей: атрибуты родовых компонентов абстрактного объекта R определяются в отношениях, которые являются агрегатными компонентами R.

Рассмотрим теперь моделирование различных дополнительных аспектов реального мира, относящихся к служащим. В качестве первого аспекта предположим, что должны моделироваться "профсоюзы" (trade union), объединяющие различные типы служащих. Будем считать значимыми следующие атрибуты профсоюза: его название (name), адрес (address) и руководитель (senior officer). На рис. 13 объект "trade union" показан в плоскости агрегации объекта "employee", а плоскость обобщения опущена (см. ).



Рис. 13. Объект "trade union", включенный в плоскость агрегации объекта "employee"

Для нас представляет также интерес "принадлежность" (affiliation) к профсоюзам типов служащих (employee-type). Поэтому мы образуем абстрактный объект "affiliation" как агрегацию "employee-type" и "trade union". Предположим, что важным атрибутом принадлежности является лицо, уполномоченное выступать от имени членов профсоюза конкретного типа служащих. Следовательно, в качестве дополнительного компонента объекта "affiliation" должен быть включен соответствующий объект, скажем, "представитель" (spokesman). После того, как это будет сделано, модель приобретет вид, показанный на рис.14.



Рис. 14. Объект "affiliation", включенный

Выбрав соответствующим образом селекторы и ключи, получаем следующее определение "affiliation":

var affiliation: generic of agregate [TN, UN] TN: key employee-type; UN: key trade union; S: spokesman end



Это определение специфицирует связь между родовыми объектами.

Мы рассмотрим далее некоторые связи на плоскости обобщения объекта "employee" (). Предположим, что компания, где работают служащие (employee), владеет парком транспортных средств (vehicle), в том числе, легковыми автомобилями (car) и грузовиками (truck). Мы будем моделировать связь между служащими и транспортными средствами, определяющую использование служащими транспортных средств. В частности, грузовики используются водителями грузовиков (trucker) для перевозки материалов, а легковые автомобили используются инженерами (engineer) для визитов на удаленные участки. Никакого другого (официального) использования транспортных средств не предусматривается. Представление "employee" и "vehicle" в плоскости обобщения показано на рис. 15.



Рис. 15. Декомпозиция объектов "employee" и "vehicle" в плоскости обобщения

Имеется два способа моделирования этой связи между служащими и транспортными средствами. Один способ состоит в том, чтобы абстрагировать единственную связь между "employee" и "vehicle" как агрегированный объект, скажем, "поездка" (trip). К сожалению, такой подход является слишком общим для того, чтобы позволить в полной мере выразить имеющуюся в виду связь. Оказалось бы, что любой служащий может бы взять для поездки любое транспортное средство, например, могло бы получиться, что секретарь ведет грузовик. Кроме того, в этом случае не существует не различаются поездки, связанные с доставкой материалов, и поездки инженеров на участки. Очень вероятно, что в зависимости от вида поездки существенны разные ее атрибуты.

Второй способ моделирования требуемой связи между служащими и транспортными средствами состоит в том, чтобы декомпозировать ее в плоскости обобщения на две связи – одна между "trucker" и "truck", а другая между "engineer" и "car". Первая связь может быть абстрагирована как агрегированный объект "перевозка" (haulage), а вторая – как "визит" (visit).


Эти объекты показаны на рис. 16.



Рис. 16. Объекты "haulage" и "visit", включенные в

Главное достоинство этого второго подхода заключается в том, что такая модель является более точным представлением реальности. Благодаря этому модель становится более понятной, а тем самым и в меньшей мере провоцирующей ошибочные доступ и манипулирование. Более того, эта модель выражает ограничения, налагаемые на объекты "haulage" и "visit" в реальном мире, а именно, то, что "haulage" должен связывать водителей грузовиков с грузовиками, а "visit" – инженеров с легковыми автомобилями. Если эти ограничения поддерживаются во время выполнения операций обновления, то можно избежать возникновения некоторых проблем целостности (например, поблем с секретарями, которые водят грузовики). Другое достоинство заключается в том, что за счет ограничения области действия связей "haulage" и "visit" явными подмножествами "employee" и "vehicle" расширяются возможности оптимизации операций выборки на более низком уровне реализации.

Рассмотрим теперь другой пример связи в плоскости обобщения объекта "employee". Предположим, что должно моделироваться назначение секретарей инженеров. Самый непосредственный способ моделирования этой связи – абстрагировать объект, скажем, "назначение" (assignment), как агрегацию объектов "secretary" и "engineer". Объект "assignment" показан справа на рис. 17. Хотя это отношение могло бы моделироваться как агрегация "employee" и "employee", такой путь привел бы к порождению излишней двусмысленности.



Рис. 17. Объекты "assignment" и "job", включенные в

Все три рассмотренные связи ("haulage", "visit" и "assignment") обладают тем свойством, что в них принимают участие служащие некоторых, но не всех типов. Проанализируем теперь связь, в которой принимают участие служащие всех типов.


Рассмотрим связь между служащими (employee) и проектами (project), которая идентифицирует работы (job), выполняемые служащими в проектах. Предполагается, что данный служащий может выполнять одновременно работы в нескольких проектах, но не несколько работ в одном и том же проекте. Эта связь лучше всего моделируется путем агрегации объектов "employee" и "project" в абстрактный объект, скажем, "job". Могут быть введены другие атрибуты "job", такие как "название" (title) и "ставка" (payrate). Объект "job" показан на .

Определение объекта "job" с соответствующим выбором селекторов и ключа приводится ниже:

var job: generic of

aggregate [E#, P#] E#: key employee; P#: key project; T: title; PR: payrate end

Здесь выбран ключ "E#, P#", поскольку, в соответствии с указанным выше ограничением, работы находятся во взаимно-однозначном соответствии с парами служащий-проект. В этом определении предполагается, что никакая декомпозиция "Работы" в плоскости обобщения не представляет интереса. Теперь предположим, что некоторых пользователей модели интересуют отдельные типы работ. Допустим, что среди проектов имеется проект, связанный с разработкой модемов, и другой, предусматривающий модернизацию принтеров. Некоторые пользователи могут пожелать рассматривать "работу в модемном проекте" (modern project job) и "работу в принтерном проекте" (printer project job) как родовые объекты. На рис.18 показано, как выглядит модель после включения в нее этих объектов как потомков "job" в плоскости обобщения.



Рис. 18. Результат декомпозиции объекта "job"в плоскости обобщения.

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


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

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

var job: generic

TN = (modemproject job, ... , printer project job) of

aggregate [E#, TN] E#: key employee; T: title; PR: payrate; TN: key job-type end

var job-type: generic of

aggregate [TN] TN: typename; P#: key project; AP: average payrate end

Заметим, что "job" представляет собой пример отношения, в котором ключ содержит домен образов.

Введение "job-type" иллюстрирует вид реструктуризации, которая часто может стать необходимой по мере эволюционирования приложения модели. В первоначальном приложении пользователей может интересовать общий класс объектов C. В процессе эволюции приложения некоторым пользователям может стать интересна только подкатегория C-объектов, у которых значением атрибута A является некоторое v1, а другим пользователи может стать интересна подкатегория со значением атрибута A, равным v2. Эти подкатегории C относительно атрибута A должны быть далее представлены как кластер в плоскости обобщения C. На этот кластер {modem project job, ... , printer project job} представляет подкатегоризацию "job" по отношению к "project".

Вообще, если появляется необходимость ввести в существующей модели подкатегоризацию некоторого объекта O по отношению к атрибуту A, то требуется следующая реструктуризация:

  1. определить новый объект S, который абстрагирует класс подкатегорий;


  2. заместить в O домен, который ссылается на A, доменом, который ссылается на S;
  3. если ключ O содержит селектор для A, заменить его селектором для S и
  4. вставить в S домен, который ссылается на A.



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