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

       

показана часть диаграммы классов


На рис. 1 показана часть диаграммы классов системы резервирования авиационных билетов. Авиалинии (Airlines) совершают рейсы между Аэропортами (Airports). ОписаниеРейса (FlightDescription) – это опубликованное описание воздушного путешествия между двумя Аэропортами (Airports). В отличие от этого, Рейс (Flight) – это реальный рейс самолета в конкретную дату. Атрибут частота (frequency) показывает дни недели, для которых применимо ОписаниеРейса. Атрибуты начальнаяДействующаяДата (startEffectiveDate) и конечнаяДействующаяДата (stopEffectiveDate) показывают период времени, в течение которого действует данное ОписаниеРейса.
Примером ОписаниеРейса является TW 250 из St. Louis в Milwaukee. Осенью 1995 г. рейс TW 250 по расписанию должен был отбывать в 7:42 утра, расчетное время полета составляло час пятнадцать минут, рейс должен был выполняться в каждый день недели, кроме субботы, и всегда самолетом DC9. Реальный Рейс TW 250 был, например, выполнен 23 октября 1995 г. со временем убытия в 7:42 утра и временем в пути один час пятнадцать минут.
В каждом ОписанииРейса присутствует ОписаниеСамолета (AircraftDescription). Например, в соответствии с ОписаниемРейса, рейс TW 250 должен был выполняться на самолете DC9. В отличие от этого, Рейсу соответствует реальный физический Самолет (Aircraft), у которого имеется уникальный регистрационныйНомер (registrationNumber).

Рис. 1. Модель классов UML для системы резервирования авиационных билетов
Модель позволяет отвечать на запросы, подобные следующему: «Найти Авиалинию, выполняющую рейсы на указанном Самолете». Инкапсуляция привела бы к следующей последовательности вызовов методов. (Заметим, что единственным осмысленным путем является Aircraft.Flight.FlightDescription.Airline.)
  1. Aircraft.getAirline() вызывает Flight.getAirline() для каждого Рейса данного Самолета. Модель классов допускает наличие нескольких Авиалиний для одного Самолета, хотя это не предусматривается. (В модели классов отсутствует ограничение, которое могло бы предотврарить это явление.) В код приложения пришлось бы вставить соответствующую проверку, которая выдавала бы в данном случае код ошибки.



  2. Flight.getAirline() вызывает FlightDescription.getAirline().

  3. FlightDescription.getAirline() возвращает Airline.

В качестве альтернативы можно было бы написать следующий SQL-запрос. (Это код расчитан на MS SQL Server и предполагает наличие очевидной схемы базы данных.) SELECT DISTINCT(FD.airlineID)
FROM Aircraft AS Ac
INNER JOIN Flight AS F
ON Ac.aircraftID = F.aircraftID
INNER JOIN FlightDescription AS FD
ON F.flightDescriptionID = FD.flightDescriptionID
WHERE Ac.aircraftID = theGivenAircraft
Теперь рассмотрим влияние пересмотра модели. Модель на рис. 1 нехороша тем, что в ней не поддерживаются сквозные полеты. Авиакомпании регулярно организуют рейсы, которые начинаются в одном городе, делают остановки в одном или нескольких промежуточных городах и завершаются в городе назначения. У всей последовательности рейсов имеется единый номер рейса, но присутствуют промежуточные аэропорты, отличные от аэропортов отправления и прибытия. Для поддержки сквозных рейсов на рис. 2 добавляется ОписаниеЭтапаРейса (FlightLegDescription).

Рис. 2. Пересмотренная модель классов UML для системы резервирования авиационных билетов с добавлением класса FlightLegDescription
Это исправление влияет на ассоциацию между Flight и FlightDescription. Соответственно, требуется переписать метод Flight.getAirline(), чтобы он вызывал новый метод FlightLegDescription.getAirline(). Никакие другие исправления в предыдущих методах не требуются. Так что при использовании искапсуляции небольшое изменение модели классов влияет только на непосредственно воздействуемые методы. В отличие от этого, сложные запросы к СУБД затрагивают много классов, поэтому вероятность потребности их переписывания гораздо больше.

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