На этом шаге рассмотрим коммуникацию объектов в UML.
Кооперирующиеся между собой объекты взаимодействуют путем обмена сообщениями. В системе, где есть одновременно активные и пассивные объекты, следует рассматривать четыре возможных комбинации.
Во-первых, сообщение может быть передано одним пассивным объектом другому такому же. Если предположить, что в любой момент времени существует лишь один поток управления, проходящий через оба объекта, такое взаимодействие – не что иное, как простой вызов операции.
Во-вторых, сообщение может быть передано от одного активного объекта другому активному. Здесь можно говорить о межпроцессной коммуникации, которая может осуществляться двумя способами.
В первом варианте некоторый активный объект может синхронно вызывать операцию другого. Такой способ имеет семантику рандеву: вызывающий объект затребует выполнение операции и ждет, пока принимающая сторона получит вызов, выполнит некоторую операцию и вернет некоторый объект (если есть что возвращать); затем оба объекта продолжают работать независимо друг от друга. В течение всего времени выполнения вызова оба потока управления будут блокированы.
Во втором варианте один активный объект может асинхронно послать сигнал другому или вызвать его операцию. Семантика такого способа напоминает почтовый ящик (mailbox): вызывающая сторона посылает сигнал или вызывает операцию, после чего продолжает работу. Тем временем получающая сторона принимает сигнал или вызов, как только будет к этому готова. Пока она обрабатывает запрос, все вновь поступающие события или вызовы ставятся в очередь. Отреагировав на запрос, принимающий объект продолжает свою работу. Семантика почтового ящика проявляется в том, что оба объекта не синхронизированы – просто один оставляет сообщение для другого.
В UML синхронное сообщение изображается закрашенной стрелкой, а асинхронное – обычной (рис. 1).
Рис.1. Коммуникация
В-третьих, сообщение может быть передано от активного объекта пассивному. Трудности возникают в случае, когда сразу несколько активных объектов передают свой поток управления одному и тому же пассивному. В такой ситуации следует очень аккуратно моделировать синхронизацию потоков.
В-четвертых, пассивный объект может передавать сообщения активному. На первый взгляд это может показаться некорректным, но если вспомнить, что каждый поток управления принадлежит некоторому активному объекту, то становится ясно, что передача пассивным объектом сообщения активному имеет ту же семантику, что и обмен сообщениями между двумя активными объектами.
С помощью ограничений можно моделировать различные вариации посылки синхронных и асинхронных сообщений. Например, для моделирования отложенного рандеву, имеющегося в языке Ada, можно воспользоваться синхронным сообщением с ограничением в формате {wait=0}, которое говорит о том, что вызывающий объект не будет дожидаться получателя. Можно смоделировать тайм-аут с помощью ограничения в формате {wait=1ms}, которое говорит, что вызывающий объект будет ждать приема сообщения получателем не более одной миллисекунды.
На следующем шаге рассмотрим синхронизацию потоков управления.