|
|
|||||||||||||||||||||||||||||
|
Использование UML при моделировании сложных систем реального времениБраин Селик (Bran Selic), ObjecTime Limited; Джим Румбаух (Jim Rumbaugh), Rational Software Corporation
ОглавлениеАннотация Встраиваемые системы реального времени, встречающиеся в таких прикладных областях, как телекоммуникации, аэрокосмические и оборонные приложения, обычно имеют тенденцию быть большими и сложными. Решающим для таких систем является то, что они должны быть разработаны в соответствии с разумной архитектурой. Хорошая архитектура не только упрощает создание первоначальной системы, но и, что более важно, обеспечивает адаптивность системы к изменениям, вызываемым постоянным появлением новых требований. В этой статье мы описываем набор конструкций, облегчающих проектирование архитектур для программ из этих предметных областей. Конструкции, полученные из подтвержденных практикой концепций изначально описанные в языке моделирования ROOM (Real-Time Object-Oriented Modeling - объектно-ориентированное моделирование систем реального времени), специфицированы с использованием стандарта UML (Unified Modeling Language - универсальный язык моделирования). В частности, мы демонстрируем, как эти архитектурные конструкции могут быть получены из более общих концепций моделирования UML путем использования мощных механизмов расширения UML. ВведениеМы используем универсальный язык моделирования UML для описания набора конструкций, походящих для моделирования важной категории программных систем реального времени. Они получены из набора концепций, изначально определенных в языке моделирования ROOM. Предметная область приложенийОдним из наиболее общих свойств всех программных систем реального времени является детерминизм, т.е. требование корректного отклика системы в рамках приемлемого временного интервала. Однако, это как будто простое свойство характеризует широкий спектр очень разных систем - от систем работающих исключительно по временному расписанию и до систем, работающих исключительно под управлением происходящих событий. С течением времени, для каждой из этих категорий систем были разработаны собственные идиомы, шаблоны проектирования и стили моделирования, которые объединили коллективный опыт многих проектов. В этом документе мы сконцентрировали внимание на основной категории систем реального времени, которые можно охарактеризовать как сложные системы, работающие под управлением событиями и использующие (в потенциале) распределенную обработку. Такие системы наиболее часто встречаются в телекоммуникациях, аэрокосмических и оборонных приложениях и в системах автоматизированного управления. Размеры и сложность этих систем требуют значительных первоначальных затрат на проектирование, обычно с привлечением больших коллективов разработчиков, за которыми следует длительный период эволюционного роста. Со временем обнаруживаются новые требования, и система частично модифицируется для их удовлетворения. В таких условиях особо важную роль приобретает архитектура системы. Она описывает структурные и поведенческие схемы, на которых базируются все остальные аспекты системы. Это программный эквивалент несущих конструкций в строительстве - любые изменения в этих основах делают необходимыми сложные и дорогостоящие изменения в основных частях системы. Таким образом, хорошо спроектированная архитектура не только упрощает разработку исходной системы, но и, что более важно, обеспечивает адаптивность системы к изменениям, вызываемым появлением новых требований. Для облегчения проектирования хороших архитектур исключительно важно выделить апробированные шаблоны проектирования предметной области в виде конструкций для моделей первого рода. Вот почему ROOM, наряду с другими, включил в себя концепции, задающие предметно-ориентированный язык описания архитектур. Эти конструкции использовались свыше десяти лет и доказали свою эффективность в сотнях различных крупномасштабных индустриальных проектов. Мы обнаружили, что это предметно-ориентированное применение может быть строго реализовано с использованием языка общего назначения UML. Использование UMLКак упоминалось выше, UML использовался для отображения этих конструкций. Мы обнаружили, что он отлично приспособлен для этих целей, так что новые для UML концепции моделирования не понадобились . С большим успехом были применены стандартные механизмы настройки UML, основанные на использовании стереотипов, присоединенных значений и ограничений. Например, центральная для ROM концепция "actor" (актер) отображалась с помощью стереотипа "capsule" (капсула) - специализации более общей концепции класса с UML. Этот стереотип добавил дополнительную предметно-ориентированную семантику к различным аспектам, связанным с понятием класса в UML (например, конечные автоматы, взаимодействия и т.п.). Возможность использования стереотипов обеспечила простой и короткий путь интерпретации набора правил правильного формирования конструкций, описывающих эту семантику. В результате, конструкции моделирования, описанные в этом документе, представляют собой библиотеку типов прикладных концепций UML, предназначенную, прежде всего, для использования при моделировании архитектур сложных систем реального времени. Их использование в комбинации со всеми другими концепциями моделирования и диаграммами UML обеспечивает целостный набор средств моделирования. Конструкции моделирования и нотацияВ этом разделе мы рассматриваем наиболее важные конструкции моделирования, используемые для представления сложных систем реального времени, и так те описываем, как они представляются и отображаются в UML. Эти конструкции могут быть разбиты на две основные группы: конструкции для моделирования структур и конструкции для моделирования поведения. Моделирование структурСтруктура системы идентифицирует моделируемые сущности и взаимосвязи между ними (например, коммуникационные взаимосвязи, отношения вложенности и т.п.). UML предоставляет два фундаментальных взаимодополняющих типа диаграмм для описания структуры систем: диаграммы классов и диаграммы взаимодействий (collaboration). Диаграммы классов описывают универсальные отношения между классами - эти отношения существуют между экземплярами классов в любом контексте. Диаграммы взаимодействий отражают отношения, которые существуют только в конкретном контексте - шаблон использования для конкретных целей, который не наследуется собственно классом. Следовательно, в диаграммах взаимодействия различается использования разных экземпляров одного и того же класса. Это различение отражается к концепции роли . В подходе к моделированию, описанном здесь, присутствует строгий акцент на использовании диаграмм взаимодействий UML исключительно для представления взаимосвязей между архитектурными элементами. Обычно, целостная спецификация структуры сложной системы реального времени получается комбинацией диаграмм классов и диаграмм взаимодействий. Конкретно мы выделяем три основных конструкции для моделирования структур:
Капсулы соответствуют концепции актора в ROOM. Они представляют собой сложные физические (возможно распределенные) архитектурные объекты, которые взаимодействуют со своим окружением через один или более ориентированных на обработку сигналов граничных объектов (boundary objects), называемых портами. Порт - физическая часть реализации капсулы, которая является посредником во взаимодействии капсулы с внешним миром - это объект, реализующий специфический интерфейс. Каждый порт капсулы играет конкретную роль во взаимодействии капсулы с другими объектами. Для отображения сложной семантики этих взаимодействий порты ассоциированы с протоколом, который определяет корректный поток информации (сигналов) между соединенными портами капсул. В этом смысле протокол отражает контрактные соглашения, существующие между капсулами. Более детально протоколы обсуждаются в разделе, посвященном моделированию поведения (2.2.1). Ограничив взаимодействия между капсулами так, чтобы они выполнялись только посредством портов, становится возможным полностью отделить их (капсул) внутреннюю реализацию от любого непосредственного знания об окружении. Это обеспечивает высокое повторное использование капсул. Коннекторы, которые соответствуют связкам (bindings) в ROOM, служат абстрактным представлением коммуникационных каналов ориентированных на передачу сигналов, которые соединяют два или более портов. Порты, связанные коннектором должны играть взаимно дополняющие, но совместимые роли в протоколе. На диаграмме взаимодействия они представляются путем ассоциирования роли, которая связана с соответствующим портом. Если мы абстрагируемся от портов в этой картине, коннекторы в действительности представляют ключевые коммуникационные отношения между капсулами. Эти отношения архитектурно значимы, так как они определяют, какие капсулы могут влиять друг на друга непосредственно. Порты включены для обеспечения инкапсуляции капсул в соответствии с принципом сокрытия информации и разделения ответственности. Функциональность простой капсулы непосредственно реализуется конечным автоматом, ассоциированным с капсулой. Более сложные капсулы объединяют конечный автомат с внутренней сетью взаимодействующих капсул нижнего уровня (sub-capsules), соединенных коннекторами. Эти капсулы нижнего уровня являются полноправными капсулами и в свою очередь могут быть подвергнуты декомпозиции на капсулы нижнего уровня. Такая декомпозиция может продолжаться до требуемой глубины, позволяя моделировать исключительно сложные структуры на основе только этого базового набора конструкций для моделирования структур. Конечный автомат (который необязателен для составных капсул), капсулы нижнего уровня и их сеть связей представляют части реализации капсулы и скрыты от внешнего наблюдателя. ПортыПорты это объекты, предназначенные для функционирования в качестве граничных объектов экземпляров капсул. Они "принадлежат" экземпляру капсулы в том смысле, что они создаются вместе со своей капсулой и уничтожаются в момент уничтожения капсулы. Каждый порт имеет свою индивидуальность и состояние, отличные от индивидуальности и состояния экземпляра капсулы, которому он принадлежит (так же как в более общем случае любая часть отличается от содержащего ее контейнера). Хотя порты являются граничными объектами, которые ведут себя как интерфейсы, они не полностью соответствуют интерфейсам в 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, то некоторый опыт работы с ними все еще необходим.
|
|