Связи
Связь — это физическое или понятийное соединение между объектами. Объект сотрудничает с другими объектами через соединяющие их связи. Связь обозначает соединение, с помощью которого:
q объект-клиент вызывает операции объекта-поставщика;
q один объект перемещает данные к другому объекту.
Можно сказать, что связи являются рельсами между станциями-объектами, по которым ездят «трамвайчики сообщений».
Связи между объектами показаны на рис. 9.5 с помощью соединительных линий. Связи представляют возможные пути для передачи сообщений. Сами сообщения показаны стрелками, отмечающими их направления, и помечены именами вызываемых операций.
Рис. 9.5. Связи между объектами
Как участник связи объект может играть одну из трех ролей:
q актер — объект, который может воздействовать на другие объекты, но никогда не подвержен воздействию других объектов;
q сервер — объект, который никогда не воздействует на другие объекты, он только используется другими объектами;
q агент — объект, который может как воздействовать на другие объекты, так и использоваться ими. Агент создается для выполнения работы от имени актера или другого агента.
На рис. 9.5 Том — это актер, Мери, Колонки — серверы, Музыкальный центр — агент.
Приведем пример. Допустим, что нужно обеспечить следующий график разворота первой ступени ракеты по углу тангажа, представленный на рис. 9.6.
Запишем абстракцию графика разворота:
with Класс_ДатчикУглаТангажа;
use Класс_ДатчикУглаТангажа;
Package Класс_ГрафикРазворота is
subtype Секунда is Natural range ...
type ГрафикРазворота is tagged private;
procedure Очистить (the: in out ГрафикРазворота);
procedure Связать (the: In out ГрафикРазворота;
teta: Угол: si: Секунда: s2: Секунда);
function УголНаМомент (the: ГрафикРазворота;
s: Секунда) return Угол;
private
…
end Класс_ГрафикРазворота;
Рис. 9.6. График разворота первой ступени ракеты
Для решения задачи надо обеспечить сотрудничество трех объектов: экземпляра класса ГрафикРазворота, РегулятораУгла и КонтроллераУгла.
Описание класса КонтроллерУгла может иметь следующий вид:
with Класс_ГрафикРазворота. Класс_РегуляторУгла;
use Класс_ГрафикРазворота. Класс_РегуляторУгла;
Package Класс_КонтроллерУгла is
type укз_наГрафик is access all ГрафикРазворота;
type КонтроллерУгла is tagged private;
procedure Обрабатывать (the: in out КонтроллерУгла;
уг: укз_наГрафик);
function Запланировано (the: КонтроллерУгла;
уг: укз_наГрафик) return Секунда;
private
type КонтроллерУгла is tagged record
регулятор: РегуляторУгла := НовРегуляторУгла
(1.1.10);
…
end Класс_КонтроллерУгла:
ПРИМЕЧАНИЕ
Операция Запланировано позволяет клиентам запросить у экземпляра Контроллера-Угла время обработки следующего графика.
И наконец, описание класса РегуляторУгла представим в следующей форме:
with Класс_ДатчикУгла. Класс_Порт;
use Класс_ДатчикУгла. Класс_Порт;
Package Класс_РегуляторУгла is
type Режим is (Увеличение. Уменьшение);
subtype Размещение is Natural range ...
type РегуляторУгла is tagged private;
function НовРегуляторУгла (номер: Размещение;
напр: Направление: порт: Порт)
return РегуляторУгла;
procedure Включить(the: in out РегуляторУгла);
procedure Выключить(the: in out РегуляторУгла);
procedure УвеличитьУгол(№е: in out
РегуляторУгла);
procedure УменьшитьУгол(the: in out
РегуляторУгла);
function ОпросСостояния(the: РегуляторУгла)
return Режим:
private
type укз_наПорт is access all Порт;
type РегуляторУгла is tagged record
Номер: Размещение;
Состояние: Режим;
Управление: укз_наПорт;
end record;
end Класс_РегуляторУгла;
Теперь, когда сделаны необходимые приготовления, объявим нужные экземпляры классов, то есть объекты:
РабочийГрафик: aliased ГрафикРазворота;
РабочийКонтроллер: aliased Контроллеругла;
Далее мы должны определить конкретные параметры графика разворота
Связать (РабочийГрафик. 30. 60. 90);
а затем предложить объекту-контроллеру выполнить этот график:
Обрабатывать (РабочийКонтроллер. РабочийГрафикАссеss);
Рассмотрим отношение между объектом РабочийГрафик и объектом РабочийКонтроллер. РабочийКонтроллер — это агент, отвечающий за выполнение графика разворота и поэтому использующий объект РабочийГрафик как сервер. В данном отношении объект РабочийКонтроллер использует объект РабочийГрафик как аргумент в одной из своих операций.