Здравствуйте, не могу найти ссылку на скачивание курса «Визуальное моделирование: теория и практика»
Номер платежа 6400454020565 |
Визуальное моделирование систем реального времени, часть I
Интерфейс
Это понятие уже рассматривалось выше, в контексте диаграмм компонент UML. Теперь оно будет изучено более детально. Интерфейс (interface) - это конструкция, которая позволяет компоненте, скрывая ее внутреннее устройство, предоставить вовне определенный способ обращения к своей функциональности. Компонента может сделать доступными через свой интерфейс следующие примитивы:
- операции - для синхронного взаимодействия ;
- переменные - опять-таки для синхронного взаимодействия;
- сообщения - для асинхронного взаимодействия.
Синхронное взаимодействие - одна компонента обратилась к другой, и пока та не ответит, обратившаяся ждет, не продолжает свою работу. Очевидно, что вызов операции - как раз синхронное взаимодействие, поскольку пока операция не выполнится, вызвавшая ее компонента не может продолжить свою работу.
С обращением к переменной - то же самое. Как правило, реализация обращений к переменной интерфейса компоненты происходит через служебные операции set (для установки значения) и get (для чтения значения), которые скрыты от пользователя интерфейса.
Асинхронное взаимодействие - компонента послала запрос и, не дожидаясь ответа на него, продолжила свою работу. Классическим способом реализовать асинхронное взаимодействие является посылка сообщения. Компонента реализует интерфейс с сообщениями, когда умеет их обрабатывать.
Рассмотрим пример. Ниже представлен интерфейс Connect, который могут реализовывать компоненты "Концентратор1" и "Концентартор2" из примера на рис. 6.1, а использовать - компоненты "Абонент1" и "Абонент2". Последние с его помощью устанавливают связь со станцией в случае исходящего вызова (операция EstablishConnect ), устанавливают/просматривают статус соединения (операции SetStatus/GetStatus ), прерывают соединение (операция ReleaseConnect ).
Interface Connect{ int EstablishConnect (int status); int SetStatus (int status); int GetStatus (); int ReleaseConnect(connection*);}
В UML, к сожалению, возможны только односторонние интерфейсы. Это соответствует концепции интерфейса в RPC ( Remout Procedure Call ), Java и других программных технологиях. Однако в системах реального времени и, в частности, в телекоммуникационных системах, дело обстоит по-другому, и есть потребность в двусторонних интерфейсах. Например, в стандарте GSM подробно описывается, что на запрос на установку соединения со стороны мобильной телефонной трубки наземная сеть может прислать либо подтверждение, что запрос принят, либо отказ в связи с плохим финансовым положением абонента, либо отказ из-за сетевых сбоев. Формат и параметры каждого из этих четырех возможных ответов тщательно описываются в стандарте. Естественно поместить и сам запрос, и все возможные ответы в один интерфейс. Назовем его I. Тогда две компоненты, взаимодействующие через такой интерфейс, будут связаны: одна - с интерфейсом I, другая - с интерфейсом I*. Последний называется сопряженным интерфейсом. Например, если в интерфейсе I посылаются сообщения m1 и m2, а принимаются - m3 и m4, то в интерфейсе I* - все наоборот. Так сделано, например, в ROOM [6.2].
Односторонние интерфейсы UML сложно расширить до двухсторонних, так как, например, в графической нотации явно указано, какая компонента реализует, а какая использует интерфейс. В случае же двустороннего интерфейса акцент на реализации и использовании интерфейса не нужен. Этот случай - пример того, как общий язык моделирования не может быть удобно использован в конкретной предметной области.
Порт
Что такое интерфейс - понятно. Тем более, что интерфейс присутствует в общеиспользуемых языках программирования, таких как Java, а также в компонентных технологиях, например COM, Java Beans и пр.
Порт (port) - это точка, через которую происходит взаимодействие компоненты с окружающей ее средой. Именно с портом, а не с компонентой вообще связываются интерфейсы, которые компонента реализует и/или требует для своей работы4Можно считать, что в обычных диаграммах компонент порты безымянны и не показываются, но на диаграммах композитных структур они показываются, их можно именовать и задавать им другие свойства.. Порт аналогичен аппаратному разъему, например, USB-разъему компьютера.
Порт позволяет также легко реализовать концепцию однотипного соединения. Одинаковых разъемов у аппаратного модуля может быть много, например, три USB-разъема у компьютера. Чтобы компактно промоделировать эту ситуацию, можно сказать, что у компоненты "Компьютер" имеется порт с множественностью три, реализующий USB-интерфейс. А поскольку у композитных компонент часто возникают однотипные соединения, то множественный порт оказывается крайне полезной конструкцией. На рис. 6.5, в порт компоненты "МатеринскаяПлатаТРС" с интерфейсом DDR (для подключения микросхем оперативной памяти) имеет множественность 8, порты с интерфейсами PCI и IDE имеют множественность 2.
Порт принадлежит типу компоненты, а у роли компоненты могут быть, соответственно, экземпляры порта. У порта может быть имя, хотя на рис. 6.5 такие имена отсутствуют, а есть только имена интерфейсов, соединенных с портами. Использовать или нет имена у портов - вопрос вкуса. Я придерживаюсь мнения, что не стоит загромождать диаграмму какой-либо информацией без настоятельной необходимости.
Далее, говоря про экземпляры порта, я буду для краткости называть их просто портами, надеясь, что читатель не запутается, уяснив из контекста, про что в точности идет речь.
Соединитель
Концепция соединения очень важна в СРВ, в частности, в телекоммуникационных системах. Как было показано выше, многочисленные соединения между узлами телекоммуникационной аппаратуры "перекочевывают" в ПО телекоммуникационных систем. И эти соединения должны вести себя также, как и аппаратные соединения: их нужно уметь устанавливать, поддерживать, завершать (в том числе, и аварийно), восстанавливать после сбоя и т. д. Кроме того, все чаще именно компоненты ПО, а не аппаратура, участвуют в непосредственной передаче данных, реализуя протоколы верхних уровней стека сетевых протоколов. При этом они часто распределены по сети и пользуются готовыми программно-аппаратными реализациями нижних уровней для передачи данных. Так что возникает надобность "прокладывать" каналы напрямую от одной ПО-компоненты к другой.
Теперь более формально о том, как такие соединения реализуются в UML 2.0. Роли компонент, через экземпляры портов, соединяются друг с другом соединителями (connectors). Соединители могут связывать экземпляр порта у некоторой роли с портом типа компоненты, в который входит данная роль (пример см. на рис. 6.5, б ). Соединители могут иметь направление и множественность на концах.
Соединители должны связывать между собой только те экземпляры портов, которые совместимы. Совместимость пары портов определяется через согласованность связанной с ними пары интерфейсов. Потому что если, например, две телекоммуникационные компоненты взаимодействуют через сеть, то их интерфейсы должны быть частями одного протокола. В ответ на посылку сообщения m1 компонента ожидает получить сообщения m2 или m3 или m4. А если она вместо этого получает сообщение m5, которое вообще не предусмотрено к обработке в этой компоненте, то система в этот момент вряд ли работает правильно.
Однако понятие согласованности интерфейсов в UML не определяется формально.
Множественность на концах соединителя аналогична множественности концов ассоциации. Ведь роли компонент, которые связывает соединитель, похожи на классы, которые связывает ассоциация, - и те и другие определяют наборы экземпляров. Соответственно, ассоциация переходит в связь между экземплярами, и соединитель - тоже. Однако в СРВ не приняты связи "один-ко-многим" и уж тем более "многие-ко-многим".
В примере на рис. 6.5 концы всех соединителей имеют множественность 0..1, и на диаграммах рассматриваемого примера она не показана. Значение множественности 0 реализуется, когда экземпляр компоненты не имеет данного соединения. Когда он его устанавливает, то реализуется значение множественности, равное единице.
Соединитель называется делегирующим, если он связывает порт типа компоненты с портом роли и роль при этом находится внутри данного типа. Такой соединитель позволяет реализовывать транзитные соединения, проходящие через границу типа компоненты. Ведь снаружи компоненты ее части не видны и с ними нельзя связаться непосредственно. А с помощью таких транзитных соединений это осуществимо. Пример делегирующего соединителя можно увидеть на рис. 6.5, б - от роли ":Видеокарта" к порту компоненты "СистемныйБлокТРС", у которого есть VGA -интерфейс.
Порты компонент, которые соединяются делегирующими соединителями с ролями внутри этих компонент, называются транзитными. Порт с интерфейсом VGA на рис. 6.5, б является транзитным. Порты, которые не соединены с частями компоненты, называются оконечными. Они ведут, например, к той части компоненты, которая не состоит из других компонент, то есть к собственному поведению компоненты. Собственное поведение часто определяют с помощью диаграмм конечных автоматов - это будет обсуждаться в следующей лекции. На рис. 6.5, б оконечным портом является тот, который предназначен для включения в электрическую сеть (с интерфейсом 220В).