Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Визуальное моделирование систем реального времени.
План лекции: 1. Многоуровневые открытые сетевые протоколы и блочная декомпозиция. 2. Композитные компоненты Многоуровневые открытые сетевые протоколы и блочная декомпозиция. Современные телекоммуникационные системы не просто должны качественно выполнять свои функции. Им нужно также быть совместимыми с другими подобными системами. Это важно по следующим соображениям. Во-первых, тогда можно пользоваться технологиями, реализованными . другими производителями, собирая систему из готовых аппаратных и про-1 граммных компонент, а самостоятельно реализуя лишь уникальную, спе- 1 пифическую функциональность. Это существенно экономит ресурсы разработки. Во-вторых, телекоммуникационные системы в большинстве слу- \ чаев являются частями глобальной мировой телекоммуникационной сети: кому, например, нужна телефонная станция, которая хорошо обслуживает абонентов одного поселка, но не позволяет им позвонить в близлежащий город, за границу и т. д.? Достичь легкого использования готовых компонент, а также обеспечить открытость и совместимость позволяет следование международным телекоммуникационным стандартам, которые развиваются уже не одно десятилетие такими комитетами, как ITU, ISO, ESTI и др. Большую роль в телекоммуникационных стандартах играет концепция многоуровневых открытых сетевых протоколов, стандартизованная международным комитетом ISO в модели ISO / OSI . В рамках данных лекций не будет рассматриваться содержательный аспект этой концепции, а также конкретные телекоммуникационные стандарты ISDN, ATM, GSM и т. д. Остановимся лишь на самой идее многоуровневого сетевого протокола, которая широко используется при про-екгаровании программно-аппаратных телекоммуникационных систем. В основе многоуровневой модели лежит разбиение сложной телекоммуникационной функциональности на уровни или «слои» - чем выше, тем абстрактнее (см. рис. 3.2).
Рис. 3.2. Уровнимногоуровневой модели Нижний уровень обслуживает верхний, предоставляя ему нужные для работы примитивы и скрывая от него логику обработки этих примитивов. Как правило, через уровни «прыгать» не принято (например, уровню N+2 нельзя напрямую обратиться к уровню N), хотя в некоторых телекоммуникационных стандартах такое встречается. Внутри себя каждый из уровней может содержать функциональные сущности («листья» декомпозиции) и подуровни (а те, в свою очередь, содержат другие подуровни и/или функциональные сущности), — см. рис. 3.3. На этом рисунке показано, что уровень N+1 содержит три функциональных сущности, уровень N — два подуровня. Декомпозиция «в глубину» может быть продолжена аналогичным образом. Еще из рис. 3.3 видно, что все соединения между уровнями, подуровнями и функциональными сущностями происходят через точки подключения, в которых определены интерфейсы взаимодействия. Рис. 3.3. Уровни, подуровни и функциональные сущности многоуровневой модели Будем называть такую декомпозицию блочной. Она отличается от других видов декомпозиции, рассмотренных при изучении UML, — например, агрегирования - следующим: • целое полностью скрывает свои части от окружения - сами части и их связи наружу не видны; • связи, идущие к целому извне, «протаскиваются» внутрь, через декомпозиционную иерархию, к его частям (как будет показано ниже, в UML для этого используются транзитные порты и делегирующие соединители).
Иерархическую блочную декомпозицию можно попробовать промоделировать цепочкой композиций классов UML (напомню, что композиция — это «сильное» агрегирование). Но нет способа задать для экземпляров классов-частей отношения, которые действуют только внутри их объекта-агрегата (такие связи можно было бы назвать локальными ассоциациями). И уж тем более остается открытым вопрос с «протаскиванием» связей через иерархию декомпозиции. Телекоммуникационные стандарты описывают различные сетевые интерфейсы, а не просто функциональность телекоммуникационных систем. Все сказанное выше применяется для этой цели следующим образом. На рис. 6.4 показано, что на каждой из взаимодействующих сетевых сторон определяется по одному «бутерброду» из уровней. На каждом из уровней между этими сетевыми сторонами определяются свои протоколы, и нижележащие уровни служат для этих протоколов транспортной средой. Самый нижний уровень является физическим и «гоняет» по проводам электрические импульсы. Выше появляются биты, пакеты и т. д. Общение двух уровней через сеть называется peer-to-peer взаимодействием.
Сообщения двух равных (peer) уровней передаются по сети не «напрямую», а «спускаются вниз», по стеку протокола одной сетевой стороны, «обрастая» дополнительной служебной информацией, а также вспомогательными сообщениями (например, для установки различных низкоуровневых каналов, гарантирующих надежность передачи). Верхнеу-ровневое сообщение может быть также разбито на части и передаваться по сети этими «кусочками». На принимающей стороне эти «кусочки* должны быть вновь собраны в исходное сообщение, а само оно «поднято наверх». Уровни, подуровни и функциональные сущности связываются друг с другом через сервисные точки (access points), в которых определяются двусторонние интерфейсы обмена сообщениями. К сервисным точкам ведут каналы снаружи блоков и от их элементов, т. е. изнутри. Ниже мы увидим, что сервисные точки моделируются портами UML 2.O. Итак, блочная декомпозиция является важнейшим принципом моделирования сложных телекоммуникационных систем. Композитные компоненты. В UML 2.O. есть композитные компоненты, которые можно изображать на специальных диаграммах композитных структур и которые, по сравнению с обычными UML-компонентами, изображаемыми на диаграммах компонент, имеют порты и аналоги каналов, а также могут иметь внутреннюю структуру, т. е. поддерживают блочную декомпозицию. Блочная декомпозиция в UML усложнена поддержкой типов. Во-первых, композитные компоненты являются типами компонент, а во-вторых, внутри себя они состоят из частей, которые принадлежат к другим типам компонент. Давайте посмотрим, чем блочная декомпозиция типов отличается от экземплярной блочной декомпозиции, которая, фактически, и рассматривалась в предыдущем разделе. Пусть создается сеть телефонных станций из трех штук для различных сельских поселков одного района. Предположим, что каждая из этих станций — особенная. Эти станции рассчитаны на разное количество абонентов (поселки могут существенно различаться численностью населения), состоят из разного оборудования, используют различное программное обеспечение и пр. Вся система разбивается на три подсистемы, каждая из них - на другие подсистемы и т. д. Получается картинка в стиле рис. 6.3. Это — экземплярная блочная декомпозиция, поскольку на части разбиваются реально существующие в системе экземпляры. Пусть теперь создается сеть из двадцати телефонных станций, для Двадцати поселков. Использовать в каждом поселке абсолютно уникальную разработку — очень накладно. Появляется несколько типов станций, которыми и «покрываются» особенности, имеющиеся в различных населенных пунктах. Каждый тип станции внутри себя устроен одинаково. Экземплярная блочная декомпозиция не подходит для моделирования структуры сложных СРВ, поскольку при этом часто возникает потребность определять множество типовых узлов и на их основе конструировать другие типы узлов. Например, типовая телефонная станция может содержать несколько однотипных пользовательских компьютеров Для рабочих мест операторов и один сервер. Типовой пользовательский компьютер (тип компоненты «ТиповаяРабочаяСтанция»), к примеру, должен включать в себя 15-дюймовый монитор, процессор по быстро-действию не ниже Pentium IV 1,6 Гц, сетевую карту, а в некоторых случаях еще и CD-устройство. Все это изображено на рисунке, выполненном в нотации диаграмм композитных структур UML 2.0. В этом примере на верхнем уровне блочной декомпозиции можно увидеть два типа компонент — «ТиповаяРабочаяСтанция» и «Типовой-Сервер». Они состоят из частей, среди которых «МониторТРС» и «Мони-торТС»* имеют одинаковый тип - «15ДМонитор». Второй уровень представлен спецификацией компонентного типа «СистемныйБлокТРС», используемого в определении типа «ТиповаяРабочаяСтанция». Наконец, на третьем уровне представлен тип компоненты «МатеринскаяПлатаТРС», который используется при определении типа «ТиповаяРабочаяСтанция». (Этот тип я раскрывать дальше не стал, ограничившись спецификацией портов и интерфейсов. Ведь где-то надо остановиться!) Все типы компонент, показанные на этом рисунке, - «ТиповаяРабочаяСтанция», «Типо-войСервер», «СистемныйБлокТРС», «МатеринскаяПлатаТРС» - являются композитными компонентами. Не будем пока рассматривать многочисленные детали композитных компонент, а остановимся на следующем вопросе: чем являются их части с точки зрения UML? Эти части называются ролями (roles) и уже многократно встречались нам - в диаграммах последовательностей и коммуникаций, временных диаграммах, при изучении коопераций. Здесь эта конструкция будет, наконец, рассмотрена детально. Роли компонент (далее - просто роли) обязательно имеют тип и служат «гнездами» для подстановки конкретных экземпляров своих типов компонент. Например, в гнездо «ПамятьТРС» можно подставить от 2 до 8 экземпляров типа «МикросхемыПамяти». А в безымянное гнездо в типе «СистемныйБлокТРС», имеющее тип «CD-устройство», может подставить один экземпляр этого типа или не одного. Роль является промежуточной абстракцией между типом и экземпляром. Она похожа на тип, так как тоже определяет множество экземпляров. Она похожа на экземпляры, так как задает строго определенное количество однотипных экземпляров (и часто - ровно один, когда не указывается в квадратных скобках множественность). Роль отличается от типа тем, что является контекстно-зависимым определением набора экземпляров. В самом деле, тип (класс, тип компоненты) определяет экземпляры, которые могут появиться практически в любом месте системы (естественно, в соответствии с правилами видимости). А экземпляры ролей могут появляться только в определенной композитной компоненте. В целом контекстной свободы у типа существенно больше, чем у роли. Имя роли задается так: <идентификатор1>: <идентификатор2>, где идентификатор 1> - это имя роли, а <Идентификатор2> - имя ее типа. Тот или иной идентификатор могут быть опущены — см. рассуждения об именах объектов в лекции про UML.
На рисунке почти все роли не имеют имен, а содержат лишь указания на типы своих компонент — здесь этого оказалось достаточно. Даны имена только двум ролям — «МониторТРС: 15ДМонитор» в компоненте «ТиповаяРабочаяСтанция» и «МониторС: 15ДМонитор» в компоненте «ТиповойСервер». В обоих этих компонентах задействованы узлы одинокого типа, поэтому естественно дать им разные имена. Еще я задал имя Pentium-процессору — Процессор ТРС, — чтобы подчеркнуть, что речь идет именно о процессоре. Имена ролей в разных композитных компонентах могут совпадать, в том числе и для ролей одинаковых типов. Ведь композитная компонента является закрытым пространством имен. Однако, во избежание путаницы, так лучше не делать. Далее, для простоты изложения, я часто буду называть и композитные компоненты, и роли, из которых они состоят, просто компонентами. Надеюсь, что читатель не запутается и из контекста поймет, что означает очередная «компонента». SADT является, по всей видимости, первой методологией, где был сформулирован и реализован принцип блочной декомпозиции. Его авторы считали, что при проектировании системы нужно поместить в модель всю информацию, которая нужна, «без купюр», но одновременно расположить ее в виде, доступном для восприятия и дальнейшей работы. Это достигалось через иерархическую декомпозицию — на одной диаграмме изображалось несколько блоков, каждый из которых далее раскрывался в следующую диаграмму и т. д. Декомпозиция поддерживалась с учетом различных особенностей нотации SADT — детали см. в [3, 12]. При этом на одной диаграмме предлагалось размещать примерно семь сущностей, что соответствует правилу «семь плюс/минус два», сформулированном в работе [ 13] еще в 1956 году (речь идет о том, что именно это количество единиц информации оптимально для одномоментного восприятия человеком). В SADT поддерживалась декомпозиция экземпляров блоков, типов там не было. В 1970-х— 1990-хгодахсоздавалсяиразвивалсяязык8ВЬдля моделирования телекоммуникационных систем [14]. В этом языке использовался тот же принцип декомпозиции, что и в SADT, но к блокам добавились каналы, точки соединения, сообщения и прочие атрибуты, необходимые для телекоммуникаций. В дальнейшем, в версиях SDL-92 и SDL-2000 появились типы блоков, наследование и другие объектно-ориентированные черты. Также были унифицированы структурные сущности — изначально, кроме блоков в SDL входили системы, подсистемы, процессы, сервисы, а теперь там есть только агенты [3, 8]. Однако, по моему мнению, эти последние новшества оказались данью моде, сделали язык более запутанным, громоздким и непонятным. В итоге, пройдя почти тридцатилетний путь развития, язык SDL уступил место UML. В начале 1990-х годов появилась методология ROOM [2] — объектно-ориентированный подход к моделированию систем реального времени. В рамках этого подхода был предложен способ для декомпозиции структуры сложных систем реального времени на основе типов и ролей, который впоследствии был использован в UML 2.O. Однако методология ROOM содержит существенно более богатые средства структурной декомпозиции, чем UML, — в частности, она включает поддержку полноценных каналов, а также сервисных соединений, широко используемых в моделях открытых многоуровневых сетевых протоколов. Интерфейс. Это понятие уже рассматривалось выше, в контексте диаграмм компонент 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 посылаются сообщения ml и т2, а принимаются — тЗ и т4, то в интерфейсе I* — все наоборот. Так сделано, например, в ROOM [2]. Односторонние интерфейсы UML сложно расширить до двухсторонних, так как, например, в графической нотации явно указано, какая компонента реализует, а какая использует интерфейс. В случае же двустороннего интерфейса акцент на реализации и использовании интерфейса не нужен. Этот случай — пример того, как общий язык моделирования не может быть удобно использован в конкретной предметной области. Порт. Что такое интерфейс — понятно. Тем более, что интерфейс присутствует в общеиспользуемых языках программирования, таких как Java, а также в компонентных технологиях, например COM, Java Beans и пр. Порт (port) — это точка, через которую происходит взаимодействие компоненты с окружающей ее средой. Именно с портом, а не с компонентой вообще связываются интерфейсы, которые компонента реализует и/или требует для своей работы*. Порт аналогичен аппаратному разъему, например, USB-разъему компьютера. Порт позволяет также легко реализовать концепцию однотипного соединения. Одинаковых разъемов у аппаратного модуля может быть * Можно считать, что в обычных диаграммах компонент порты безымянны и не показываются, но на диаграммах композитных структур они показываются, их можно именовать и задавать им другие свойства. много, например, три USB-разъема у компьютера. Чтобы компактно промоделировать эту ситуацию, можно сказать, что у компоненты «Компьютер» имеется порт с множественностью три, реализующий USB-интер-фейс. А поскольку у композитных компонент часто возникают однотипные соединения, то множественный порт оказывается крайне полезной конструкцией. На рис. 6.5, в порт компоненты «МатеринскаяПлатаТРС» с интерфейсом DDR (для подключения микросхем оперативной памяти) имеет множественность 8, порты с интерфейсами PCI и IDE имеют множественность 2. Порт принадлежит типу компоненты, а у роли компоненты, могут быть, соответственно, экземпляры порта. У порта может быть имя, хотя на рис. 6.5 такие имена отсутствуют, а есть только имена интерфейсов, соединенных с портами. Использовать или нет имена у портов — вопрос вкуса. Я придерживаюсь мнения, что не стоит загромождать диаграмму какой-либо информацией без настоятельной необходимости. Далее, говоря про экземпляры порта, я буду для краткости называть их просто портами, надеясь, что читатель не запутается, уяснив из контекста, про что в точности идет речь. Соединитель. Концепция соединения очень важна в СРВ, в частности, в телекоммуникационных системах. Как было показано выше, многочисленные соединения между узлами телекоммуникационной аппаратуры «перекочевывают» в ПО телекоммуникационных систем. И эти соединения должны вести себя также, как и аппаратные соединения: их нужно уметьдстанавливать, поддерживать, завершать (в том числе, и аварийно), восстанавливать после сбоя и т. д. Кроме того, все чаще именно компоненты ПО, а не аппаратура, участвуют в непосредственной передаче данных, реализуя протоколы верхних уровней стека сетевых протоколов. При этом они часто распределены по сети и пользуются готовыми программно-аппаратными реализациями нижних уровней для передачи данных. Так что возникает надобность «прокладывать» каналы напрямую от одной ПО-компоненты к другой. Теперь более формально о том, как такие соединения реализуются в UML 2.O. Роли компонент, через экземпляры портов, соединяются друг с другом соединителями (connectors). Соединители могут связывать экземпляр порта у некоторой роли с портом типа компоненты, в который входит данная роль (пример см. на рис. 6.5, б). Соединители могут иметь направление и множественность на концах. Соединители должны связывать между собой только те экземпляры портов, которые совместимы. Совместимость пары портов определяется через согласованность связанной с ними пары интерфейсов. Потому что если, например, две телекоммуникационные компоненты взаимодействуют через сеть, то их интерфейсы должны быть частями одного протокола. В ответ на посылку сообщения ml компонента ожидает получить сообщения т2 или тЗ или т4. А если она вместо этого получает сообщение ш5, которое вообще не предусмотрено к обработке в этой компоненте, то система в этот момент вряд ли работает правильно. Однако понятие согласованности интерфейсов в UML не определяется формально. Согласованность двусторонних интерфейсов определяется просто: если интерфейс II является сопряженным к 12, то, значит, они совместимы и соответствующие экземпляры портов можно связывать соединителем 1. В данном случае, когда у нас есть только односторонние интерфейсы, совместимость нужно как-то явно задавать, например, что II совместим с 12 и 13. При связывании двух экземпляров портов соединителем графический редактор должен проверить, являются ли их интерфейсы совместимыми. И если не являются, соединитель не должен быть создан. В UML никак не определяется концепция согласованности интерфейсов. Множественность на концах соединителя аналогична множественности концов ассоциации. Ведь роли компонент, которые связывает соединитель, похожи на классы, которые связывает ассоциация, — и те и другие определяют наборы экземпляров. Соответственно, ассоциация переходит в связь между экземплярами, и соединитель - тоже. Однако в СРВ не приняты связи «один-ко-многим» и уж тем более «многие-ко-многим». Исключение составляют широковещательные (broadcast) соединения, а также концепция сервисных соединений, реализованная, например, в ROOM [2]. Множественность соединителей используется, в основном, для ролей в других структурных классификаторах, например, в кооперациях. В примере на рисунке концы всех соединителей имеют множественность 0..1, и на диаграммах рассматриваемого примера она не показана. Значение множественности 0 реализуется, когда экземпляр компоненты не имеет данного соединения. Когда он его устанавливает, то реализуется значение множественности, равное единице. Соединитель называется делегирующим, если он связывает порт типа компоненты с портом роли и роль при этом находится внутри данно- j го типа. Такой соединитель позволяет реализовывать транзитные соединения, проходящие через границу типа компоненты. Ведь снаружи ком- ] поненты ее части не видны и с ними нельзя связаться непосредственно. А с помощью таких транзитных соединений это осуществимо. Пример делегирующего соединителя можно увидеть на рисунке, б - от роли «:Видеокарта» к порту компоненты «СистемныйБлокТРС», у которого есть VGA-интерфейс. Как уже упоминалось выше, соединитель является аналогом провода, соединяющего два аппаратных устройства. В языке SDL, предназначенном для моделирования телекоммуникационных систем, соединителям UML соответствуют каналы, где можно определять сообщения и много других интересных с точки зрения телекоммуникаций свойств. В методологии ROOM, откуда соединители попали в UML, они имеют более строгую формальную семантику. Соединители в UML развились из ассоциаций с попыткой обобщить концепцию соединения ролей. С их помощью соединяются, например, роли классов на диаграммах композитных структур для коопераций. При этом там порты не используются (можно считать, что они есть, но являются фиктивными и на диаграмме не показываются). Порты компонент, которые соединяются делегирующими соединителями с ролями внутри этих компонент, называются транзитными. Порт с интерфейсом VGA на рисунке, б является транзитным. Порты, которые не соединены с частями компоненты, называются оконечными. Они ведут, например, к той части компоненты, которая не состоит из других компонент, то есть к собственному поведению компоненты. Собственное поведение часто определяют с помощью диаграмм конечных автоматов — это будет обсуждаться в следующей лекции. На рис. рисунке, б оконечным портом является тот, который предназначен для включения в электрическую сеть (с интерфейсом 220В).
Лекция №4. |
Последнее изменение этой страницы: 2019-04-21; Просмотров: 219; Нарушение авторского права страницы