Вы находитесь на страницах старой версии сайта.
Переходите на новую версию Interface.Ru

Использование UML при моделировании сложных систем реального времени
(Часть 2)

Предидущая часть

© Браин Селик (Bran Selic), ObjecTime Limited
© Джим Румбаух (Jim Rumbaugh), Rational Software Corporation
Переведено БНТП по заказу Interface Ltd.

Порты

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

Хотя порты являются граничными объектами, которые ведут себя как интерфейсы, они не полностью соответствуют интерфейсам в UML. Интерфейсы в UML - это исключительно поведенческие абстракции, не имеющие реализующих их структур. Порт, с другой стороны, включает и структуру и поведение. Это композитная часть капсулы, а не просто ограничение на ее поведение. Порт реализует архитектурный шаблон, который мы можем назвать "явный интерфейс" (manifest interface).

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

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

Релейные порты

Релейные порты просто передают сигналы дальше. Они обеспечивают "открытие" инкапсулирующей оболочки капсулы, которое может быть использовано ее капсулами нижнего уровня для взаимодействия с внешним миром без реального раскрытия себя вовне (и наоборот). Релейные порты соединены через коннекторы с капсулами нижнего уровня и обычно так же подсоединены снаружи с некой другой "равноправной" капсулой. Они получают сигналы с обеих сторон и просто транслируют их дальше, сохраняя направление потока сигналов. Это выполняется без задержки или потери информации, если к противоположной стороне присоединен коннектор. В противном случае сигнал теряется.

Релейные порты обеспечивают прямую (без накладных расходов) передачу сигналов направленных капсуле ее капсулам нижнего уровня без необходимости вмешательства конечного автомата капсулы. Релейные порты могут появляться только на границе капсулы и, следовательно, всегда имеют публичную (public) видимость.

Конечные порты

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

Так же как и релейные порты, конечные порты могут появляться на границах капсулы с публичной видимостью. Эти порты называются публичными конечными портами. Такие порты являются граничными объектами, как для капсулы, так и для конечного автомата, содержащегося в капсуле . Кроме того, конечные порты могут еще появляться полностью внутри капсулы, как часть реализующей ее внутренней структуры. Эти порты используются конечным автоматом для взаимодействия с капсулами нижнего уровня или внешними слоями поддержки реализации . Эти внутренние конечные порты называются защищенными (protected) конечными портами и имеют защищенную (protected) видимость.

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

Моделирование в UML

В терминах UML, порты моделируются с помощью стереотипа "port", стереотипа концепции Class в UML. Как указывалось ранее, тип порта определяется протокольной ролью, выполняемой этим портом. Так как протокольные роли - это абстрактные классы, реальные классы, относящиеся к этому экземпляру, являются реализациями протокольной роли, связанной с портом. В UML отношение между портом и протокольной ролью отображается как реализующее отношение. В качестве нотации для этого используется пунктирная линия с заполненным треугольником для острия стрелки на специфицируемом конце. Это форма генерализации, где исходный элемент - порт - наследует только спецификацию поведения целевой протокольной роли, но не ее структуру.

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

На рис. 1 показан пример порта, поименованного b, и принадлежащего классу капсул CapsuleClassA. Этот порт реализует роль master определенную в классе протоколов ProtocolA. Обратите внимание, что реальный класс портов PortClassX, является классом реализации, который может варьироваться от реализации к реализации, что обычно не представляет интереса для разработчика до начала стадии реализации. Вместо того, информация, которая представляет интерес, - это протокольная роль, выполняемая портом. По этой причине и для удобства нотации, нотация, показанная на рис. 1, обычно не используется и заменяется более компактной формой, описанной в следующих разделах.

Нотация

На диаграмме классов порты капсулы перечислены в специально поименованном списке в отдельной секции, как это показано на рис. 2. Эта секция со списком портов (ports) обычно идет за секциями со списками атрибутов и операторов. Такая нотация использует преимущество особенности UML, позволяющей добавлять специфические поименованные секции.

Все внешние порты (релейные порты и публичные конечные порты) имеют публичную видимость, тогда как внутренние порты имеют защищенную видимость (например, порт b2 на рис. 2). Протокольная роль (тип) порта обычно идентифицируется именем пути, так как имя протокольной роли уникально только в рамках области определения данного протокола. Например, на рис. 2 порт b играет роль master, определенную в классе протоколов с именем ProtocolA. Для очень распространенного случая бинарных протоколов используется более простая нотация: суффиксный символ тильда ("~") используется для идентификации подчиненной (за определениями для этих терминов обратитесь к разделу 2.2.1) протокольной роли (например, порт b2) в то время как имя базовой роли используется неявно без специальной нотации (порт b1). Порты с множественностью отличной от 1, включают коэффициент мультипликации в квадратных скобках. Например, порт b1[3] имеет коэффициент мультипликации ровно 3, тогда как порт обозначенный b5[0..2] имеет переменное число экземпляров, не превышающее 2.

На рис. 2 показано, как порты отображаются на диаграмме классов. Они также отображаются на диаграммах взаимодействия, которые описывают внутреннюю декомпозицию капсулы. На этих диаграммах объекты представляются соответствующими ролями классификаторов - капсулы нижнего уровня с помощью ролей капсул и порты с помощью ролей портов. Для уменьшения графической перегруженности, роли портов в основном показываются в виде пиктограмм, маленькими черными или белыми квадратами. Публичные порты представляются пиктограммой роли порта, которая пересекается границей роли соответствующей капсулы, как показано на рис. 3. Эта сокращенная нотация позволяет им быть связанными как изнутри, таки снаружи капсулы, без ненужного пересечения линий и также идентифицирует их как граничные объекты.

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

Для бинарных протоколов используются пиктограммы дополнительного стереотипа: порт, играющий подчиненную роль, изображается белым (вместо черного) квадратом. В этом случае имя протокола и суффикс тильда достаточны для идентификации протокольной роли как подчиненной; имя протокольной роли избыточно и может быть опущено. Подобно этому, использование имени протокольной роли самого по себе для черного квадрата указывает на базовую роль в протоколе. Например, если роль "master" в протоколе ProtQ (Рис. 3) объявлена как базовая, тогда диаграммы на Рис. 3 и Рис. 4 эквивалентны. Это соглашение облегчает возможность видеть, что дополнительные роли протокола связаны.

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

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

В этом случае пиктограмма конечного порта изображается соединенной с небольшим прямоугольником со скругленными углами, что служит пиктографическим отображением конечного автомата капсулы. Например, порт x1 публичный (подчиненный) конечный порт, а порт x3 защищенный конечный порт. (Заметьте, что хотя на диаграмме взаимодействия присутствует несколько пиктограмм конечных автоматов, у капсулы не может быть больше одного конечного автомата. Конечные порты могут быть соединены с единственной пиктограммой конечного автомата, но часто в этом случае графические связи будут спутаны, так что пиктограмма конечного автомата может дублироваться.) Релейные порты идентифицируются фактом своей связи с портом капсулы нижнего уровня (например, порт x2). Порты, не присоединенные ни к пиктограмме конечного автомата, ни к порту капсулы нижнего уровня, являются недетерминированными. Это значит, их классификация в качестве конечных или релейных портов отложена и обычно разрешается на уровне подклассов, или они могут просто оставаться не присоединенными.

Коннекторы

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

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

Моделирование в UML

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

Нотация

Так как коннекторы не требуют никаких специальных стереотипов, они не требуют никаких расширений нотации. На диаграмме классов для представления коннекторов могут использоваться ассоциации. Вне зависимости от того представлен коннектор на диаграмме классов или нет, он должен обязательно присутствовать на диаграмме взаимодействия класса капсулы, которому он принадлежит. Коннекторы бинарных протоколов изображаются линией между двумя дополняющими ролями портов. Пример коннектора бинарного протокола можно увидеть выше на рисунках 3 и 6.

Коннекторы для трехместных протоколов и протоколов более высоких порядков представляются с использованием стандартной нотации UML для n-арных ассоциаций - в виде ромба. Так как протоколы высоких порядков не были реализованы в ROOM, то некоторый опыт работы с ними все еще необходим.

За дополнительной информацией обращайтесь в компанию Interface Ltd.

Обсудить на форуме

Рекомендовать страницу

INTERFACE Ltd.
Телефон/Факс: +7 (495) 925-0049
Отправить E-Mail
http://www.interface.ru
Rambler's Top100
Ваши замечания и предложения отправляйте редактору
По техническим вопросам обращайтесь к вебмастеру