Лабораторная работа 6 диаграммы компонентов общая информация
Скачать 197.5 Kb.
|
Лабораторная работа №6 ДИАГРАММЫ КОМПОНЕНТОВ Общая информация Полный проект программной системы представляет собой совокупность моделей логического и физического уровней, которые должны быть согласованы между собой. В языке UML для физического представления моделей систем используются диаграммы реализации (implementation diagrams), которые включают в себя диаграмму компонентов и диаграмму развертывания. Диаграмма компонентов, в отличие от ранее рассмотренных диаграмм, описывает особенности физического представления системы. Она позволяет определить архитектуру разрабатываемой системы, установив зависимости между программными компонентами, в роли которых может выступать исходный и исполняемый код. Основными графическими элементами диаграммы компонентов являются компоненты, интерфейсы и зависимости между ними. Диаграмма компонентов разрабатывается для следующих целей: визуализации общей структуры исходного кода программной системы; спецификации исполняемого варианта программной системы; обеспечения многократного использования отдельных фрагментов программного кода; представления концептуальной и физической схем баз данных. В разработке диаграмм компонентов участвуют как системные аналитики и архитекторы, так и программисты. Диаграмма компонентов обеспечивает согласованный переход от логического представления к конкретной реализации проекта в форме программного кода. Одни компоненты могут существовать только на этапе компиляции программного кода, другие на этапе его исполнения. Диаграмма компонентов отражает общие зависимости между компонентами, рассматривая последние в качестве классификаторов. Компоненты Для представления физических сущностей в языке UML применяется специальный термин - компонент (component). Компонент реализует некоторый набор интерфейсов и служит для общего обозначения элементов физического представления модели. Для графического представления компонента используется специальный символ - прямоугольник со вставленными слева двумя более мелкими прямоугольниками. Внутри большого прямоугольника записывается имя компонента и, при необходимости, некоторая дополнительная информация. Изображение этого символа может незначительно варьироваться в зависимости от характера ассоциируемой с компонентом информации. Имя компонента подчиняется общим правилам именования элементов модели в языке UML и может состоять из любого числа букв, цифр и некоторых знаков препинания. Отдельный компонент может быть представлен на уровне типа или на уровне экземпляра. Графическое изображение в обоих случаях одинаковое, но правила записи имени компонента отличаются. Если компонент представляется на уровне типа, то в качестве его имени записывается только имя типа с заглавной буквы. Если же компонент представляется на уровне экземпляра, то в качестве его имени записывается <имя компонента>':'<имя типаХ>. При этом вся строка имени подчеркивается. В качестве простых имен принято использовать имена исполняемых файлов (с указанием расширения ехе после точки-разделителя), динамических библиотек (расширение dll), Web-страниц (расширение html), текстовых файлов (расширения txt или doc) или файлов справки (hip), файлов баз данных (DB) или файлов с исходными текстами программ (расширения h, cpp для языка C++, расширение java для языка Java), скрипты (pi, asp) и другие. Поскольку конкретная реализация логического представления модели системы зависит от используемого программного инструментария, то и имена компонентов определяются особенностями синтаксиса соответствующего языка программирования. В отдельных случаях к простому имени компонента может быть добавлена информация об имени объемлющего пакета и о конкретной версии реализации данного компонента. В этом случае номер версии записывается как помеченное значение в фигурных скобках. В других случаях символ компонента может быть разделен на секции, чтобы явно указать имена реализованных в нем интерфейсов. Поскольку компонент как элемент физической реализации модели представляет отдельный модуль кода, иногда его комментируют с указанием дополнительных графических символов, иллюстрирующих конкретные особенности его реализации. Эти дополнительные обозначения для примечаний не специфицированы в языке UML, однако их применение упрощает понимание диаграммы компонентов, повышая наглядность физического представления. В языке UML выделяют три вида компонентов: развертывания, которые обеспечивают непосредственное выполнение системой своих функций. Такими компонентами могут быть динамически подключаемые библиотеки с расширением dll, Web-страницы на языке разметки гипертекста с расширением html и файлы справки с расширением hlp; рабочие продукты. Как правило, это файлы с исходными текстами программ, например, с расширениями h или срр для языка C++; исполнения, представляющие собой исполняемые модули - файлы с расширением ехе. Эти элементы иногда называют артефактами, подчеркивая при этом их законченное информационное содержание, зависящее от конкретной технологии реализации соответствующих компонентов. Другим способом спецификации различных видов компонентов является явное указание его стереотипа компонента перед именем. В языке UML для компонентов определены следующие стереотипы: библиотека (library) - определяет первую разновидность компонента, который представляется в форме динамической или статической библиотеки; таблица (table) - также определяет первую разновидность компонента, который представляется в форме таблицы базы данных; файл (file) - определяет вторую разновидность компонента, который представляется в виде файлов с исходными текстами программ; документ (document) - определяет вторую разновидность компонента, который представляется в форме документа; исполнимый (executable) — определяет третий вид компонента, который может исполняться в узле. Интерфейсы Следующим элементом диаграммы компонентов являются интерфейсы. В общем случае, интерфейс графически изображается окружностью, которая соединяется с компонентом отрезком линии без стрелок. Имя интерфейса должно начинаться с заглавной буквы "I" и записываться рядом с окружностью. Семантически линия означает реализацию интерфейса, а наличие интерфейсов у компонента означает, что данный компонент реализует соответствующий набор интерфейсов. Другим способом представления интерфейса на диаграмме компонентов является его изображение в виде прямоугольника класса со стереотипом «интерфейс» и возможными секциями атрибутов и операций. Как правило, этот вариант обозначения используется для представления внутренней структуры интерфейса, которая может быть важна для реализации. При разработке программных систем интерфейсы обеспечивают не только совместимость различных версий, но и возможность вносить существенные изменения в одни части программы, не изменяя другие ее части. Таким образом, назначение интерфейсов существенно шире, чем спецификация взаимодействия с пользователями системы (актерами). Зависимости В общем случае отношение зависимости также было рассмотрено ранее. Напомним, что зависимость не является ассоциацией, а служит для представления только факта наличия такой связи, когда изменение одного элемента модели оказывает влияние или приводит к изменению другого элемента модели. Отношение зависимости на диаграмме компонентов изображается пунктирной линией со стрелкой, направленной от клиента (зависимого элемента) к источнику (независимому элементу). Зависимости могут отражать связи модулей программы на этапе компиляции и генерации объектного кода. В другом случае зависимость может отражать наличие в независимом компоненте описаний классов, которые используются в зависимом компоненте для создания соответствующих объектов. Применительно к диаграмме компонентов зависимости могут связывать компоненты и импортируемые этим компонентом интерфейсы, а также различные виды компонентов между собой. В первом случае рисуют стрелку от компонента-клиента к импортируемому интерфейсу. Наличие стрелки означает, что компонент не реализует соответствующий интерфейс, а использует его в процессе своего выполнения. Причем на этой же диаграмме может присутствовать и другой компонент, который реализует этот интерфейс. Другим случаем отношения зависимости на диаграмме компонентов является отношение между различными видами компонентов. Наличие подобной зависимости означает, что внесение изменений в исходные тексты программ или динамические библиотеки приводит к изменениям самого компонента. При этом характер изменений может быть отмечен дополнительно. На диаграмме компонентов могут быть также представлены отношения зависимости между компонентами и реализованными в них классами. Эта информация имеет значение для обеспечения согласования логического и физического представлений модели системы. Если требуется подчеркнуть, что некоторый компонент реализует отдельные классы, то для обозначения компонента используется расширенный символ прямоугольника. При этом прямоугольник компонента делится на две секции горизонтальной линией. Верхняя секция служит для записи имени компонента, а нижняя секция — для указания дополнительной информации. Внутри символа компонента могут изображаться другие элементы графической нотации, такие как классы (компонент уровня типа) или объекты (компонент уровня экземпляра). В этом случае символ компонента изображается таким образом, чтобы вместить эти дополнительные символы. Объекты, которые находятся в отдельном компоненте-экземпляре, изображаются вложенными в символ данного компонента. Подобная вложенность означает, что выполнение компонента влечет выполнение соответствующих объектов. Рекомендации по построению диаграммы компонентов Разработка диаграммы компонентов предполагает использование информации как о логическом представлении модели системы, так и об особенностях ее физической реализации. До начала разработки необходимо принять решения о выборе вычислительных платформ и операционных систем, на которых предполагается реализовывать систему, а также о выборе конкретных баз данных и языков программирования. После этого можно приступать к общей структуризации диаграммы компонентов. В первую очередь, необходимо решить, из каких физических частей (файлов) будет состоять программная система. На этом этапе следует обратить внимание на такую реализацию системы, которая обеспечивала бы не только возможность повторного использования кода за счет рациональной декомпозиции компонентов, но и создание объектов только при их необходимости. Речь идет о том, что общая производительность программной системы существенно зависит от рационального использования вычислительных ресурсов. Для этой цели необходимо большую часть описаний классов, их операций и методов вынести в динамические библиотеки, оставив в исполняемых компонентах только самые необходимые для инициализации программы фрагменты программного кода. После общей структуризации физического представления системы необходимо дополнить модель интерфейсами и схемами базы данных. При разработке интерфейсов следует обращать внимание на согласование (стыковку) различных частей программной системы. Включение в модель схемы базы данных предполагает спецификацию отдельных таблиц и установление информационных связей между таблицами. Завершающий этап построения диаграммы компонентов связан с установлением и нанесением на диаграмму взаимных связей между компонентами, а также отношений реализации. Эти отношения должны иллюстрировать все важнейшие аспекты физической реализации системы, начиная с особенностей компиляции исходных текстов программ и заканчивая исполнением отдельных частей программы на этапе ее выполнения. Для этой цели можно использовать различные виды графического изображения компонентов. При разработке диаграммы компонентов следует придерживаться общих принципов создания моделей на языке UML. В частности, необходимо использовать уже имеющиеся в языке UML компоненты и стереотипы. Для большинства типовых проектов этого набора элементов может оказаться достаточно для представления компонентов и зависимостей между ними. Если проект содержит некоторые физические элементы, описание которых отсутствует в языке UML, то следует воспользоваться механизмом расширения и использовать дополнительные стереотипы для отдельных нетиповых компонентов или помеченные значения для уточнения их отдельных характеристик. Правила работы Чтобы создать UML-схему компонентов, в меню Архитектура щелкните Создать схему. Компонент — это модульная единица, заменяемая в пределах среды. Его внутренние составляющие скрыты, но доступ к функциям компонента можно получить с помощью одного или нескольких четко определенных предоставленных интерфейсов. Компонент также может иметь требуемые интерфейсы. Требуемый интерфейс определяет, какие функции и службы он требует от других компонентов. Объединив предоставленные и требуемые интерфейсы нескольких компонентов, можно создать более крупный компонент. Можно сказать, что вся программная система, по сути, представляет собой компонент. Создание схем компонентов имеет несколько преимуществ. Анализ основных элементов системы позволяет команде разработчиков понять принципы существующей системы и создать новую. Представление системы в качестве коллекции компонентов с четко определенными предоставленными и требуемыми интерфейсами позволяет более эффективно разделить компоненты. В свою очередь, это облегчает понимание конструкции системы и ее корректирование при изменении требований. Можно использовать схему компонентов, чтобы представить конструкцию системы независимо от того, какой язык или платформа используется сейчас или будет использоваться в будущем. Отношение к другим схемам Можно использовать схему компонентов совместно с другими схемами.
Основные этапы создания схем компонентов Создание схемы компонентов В меню Архитектура выберите пункт Создать схему. В разделе Шаблоны щелкните UML-схема компонентов. Назовите схему. В области Добавить в проект моделирования выделите существующий проект моделирования в решении или выберите Создать новый проект моделирования и нажмите кнопку ОК. Новая схема компонентов отображается на панели элементов Схема компонентов UML. Панель элементов содержит требуемые элементы и отношения. Создание компонентов Создайте компонент (1) для каждой крупной функциональной единицы в системе или приложении. В качестве примеров можно привести приложение, аппаратное средство, веб-службу, сборку .NET, программный класс или группу классов или любой другой отделимый сегмент программы. Создание компонентов Щелкните Компонент на панели элементов, затем щелкните пустую область схемы. - или - Скопируйте и вставьте существующий компонент. Найдите существующий компонент на схеме или в Проводнике по моделям UML. Щелкните компонент правой кнопкой мыши и выберите Копировать. Откройте схему, на которой необходимо отобразить скопированный компонент. Щелкните правой кнопкой мыши пустую область схемы и выберите Вставить. Копия компонента отображается с новым именем. Щелкните имя компонента, чтобы изменить его. Щелкните шеврон (5), если нужно отобразить только заголовок компонента. Отображение портов компонента Порт (2, 3) представляет группу сообщений или вызовов операций, входящих в компонент или выходящих из него. Группа описывается интерфейсом, который определяет тип порта. Порт может либо предоставлять, либо требовать интерфейс. Порт с предоставленным интерфейсом (2) предоставляет операции, реализуемые компонентом, которые также могут использоваться другими компонентами. В качестве примеров можно назвать пользовательский интерфейс, веб-службу, интерфейс .NET или коллекцию функций на любом языке программирования. Порт с требуемым интерфейсом (3) представляет требование компонента к группе операций или служб, которые должны быть предоставлены другими компонентами или внешними системами. Например, веб-браузер требует веб-серверы, а надстройка приложения требует службы из приложения. Компонент может иметь неограниченное число портов. Добавление портов в компонент На панели элементов щелкните Предоставленный интерфейс или Требуемый интерфейс. Щелкните компонент, который необходимо добавить в интерфейс. На границе компонента появляется порт. Новый интерфейс создается как тип порта. Этот интерфейс отображается в Проводнике по моделям UML. Перетащите порт через границу компонента и разместите его, где нужно. Перетащите метку порта, чтобы скорректировать его расположение. Щелкните метку, чтобы изменить ее. Метка показывает имя интерфейса. Если изменить ее, изменится и имя интерфейса. Ссылки между компонентами Используйте зависимость (4), чтобы показать, что требования одного компонента можно удовлетворить операциями или службами, предоставленными другим компонентом. Как показать, что предоставленный интерфейс может удовлетворить условия требуемого интерфейса На панели элементов щелкните Зависимость. Щелкните порт с требуемым интерфейсом одного компонента, затем щелкните порт с предоставленным интерфейсом другого компонента. Следует избегать создания циклов зависимости, в которых каждый компонент группы зависит от всех остальных компонентов. Добавление в компонент порта для существующего интерфейса В Проводнике по моделям UML найдите интерфейс и перетащите его в компонент. – или – Скопируйте и вставьте ссылку на интерфейс из схемы. На схеме классов или схеме компонентов щелкните интерфейс правой кнопкой мыши и выберите Копировать. На схеме компонентов щелкните компонент правой кнопкой мыши и выберите Вставить ссылку. В компоненте появляется предоставленный интерфейс. Рядом появляется тег действия. Если необходимо создать требуемый интерфейс, щелкните тег действия и выберите Преобразовать в требуемый интерфейс. Отображение внутренних частей компонента Можно разместить части (3) в компоненте (1), чтобы показать, что он состоит из более мелких компонентов, взаимодействующих друг с другом. Схема на иллюстрации показывает, что каждый экземпляр веб-службы Dinner Now содержит один экземпляр сервера "Клиенты" и один экземпляр сервера "Кухня". Часть — это свойство родительского компонента. Отношения между ними можно сравнить с тем, как атрибут принадлежит к обычному классу. Часть имеет собственный тип, который, как правило, также является компонентом. Метка части имеет ту же форму, что и обычный атрибут. Внутри родительского компонента каждая часть показывает предоставляемые и требуемые интерфейсы, определенные для ее типа (4, 5). Операции или службы, требуемые одной частью, могут быть предоставлены другой. Можно использовать соединители Сборки части, чтобы показать, как части соединены друг с другом (6). Также можно показать, что одна из частей родительского компонента фактически предоставляет или требует его интерфейс. Можно подключить порт родительского компонента к порту внутренней части, воспользовавшись отношением Делегирование (9). Оба порта должны относиться к одному виду (предоставленные или требуемые) и иметь совместимые типы интерфейса. Новую часть можно создать либо с помощью нового типа, либо из существующего типа. Добавление частей в компонент Создайте часть для каждой крупной функциональной единицы, которая является частью родительского компонента. Щелкните Компонент на панели элементов, затем щелкните внутри родительского компонента (1). Новая часть (3) появляется внутри родительского компонента. В Проводнике по моделям UML создается новый компонент. Это тип новой части. - или - Перетащите существующий компонент из Проводника по моделям UML в родительский компонент. Новая часть (3) появляется внутри родительского компонента. Ее тип — это компонент, перемещенный из Проводника по моделям UML. - или - На схеме или в Проводнике по моделям UML щелкните компонент правой кнопкой мыши и выберите Копировать. Щелкните родительский компонент правой кнопкой мыши и выберите Вставить ссылку. Новая часть (3) появляется внутри родительского компонента. Ее тип — это скопированный компонент. Щелкните имя новой части, чтобы изменить его. Изменить ее тип невозможно. В новую часть можно добавить предоставленные и требуемые интерфейсы (4, 5). Выберите Предоставленный интерфейс или Требуемый интерфейси щелкните часть. - или - Перетащите существующий интерфейс из Проводника по моделям UML в часть. Интерфейсы добавляются в тип части и отображаются в самой части. При необходимости корректируется размер родительского компонента. Соедините части друг с другом. Используйте инструмент Зависимость, чтобы соединить порты разных частей (6). Соедините части с портами родительского компонента. Создайте один или несколько портов (7) в родительском компоненте. Выберите Требуемый интерфейс или Предоставленный интерфейс на панели элементов и щелкните родительский компонент. Делегируйте (9) порт одной или нескольким частям. Последовательно щелкните инструмент Делегирование, порт в родительском компоненте и порт в части. Можно соединить порты, предоставляющие или требующие интерфейсы аналогичным способом. Отображение частей части После разложения компонента на части каждый тип части можно дополнительно разложить на внутренние части. Удобнее разместить каждый слой разложения на отдельной схеме компонентов. Сначала нужно найти тип части. Например, на иллюстрации одна из частей называется DNCustomerServer, а ее тип представляет собой компонент, который называется CustomerServer. Этот тип можно найти в Проводнике по моделям UML и поместить его на другую схему. Затем можно создавать внутренние части типа. Размещение типа части на схеме Определите полное имя для типа части. Щелкните часть правой кнопкой мыши и выберите пункт Свойства. Имя типа отображается в поле Тип окна свойств. Найдите тип части в Проводнике по моделям UML. Щелкните Вид, выберите Другие окна и щелкните Проводник по моделям UML. Разверните проект и (при необходимости) любой пакет, к которому принадлежит тип. Тип отобразится в списке как Компонент. При необходимости его имя можно изменить здесь. Откройте или создайте другую схему компонентов. Перетащите тип из Проводника по моделям UML на схему. Представление типа отображается как компонент на схеме. Он имеет те же интерфейсы, которые были определены для части. Теперь можно добавлять части в компонент. Конструирование компонента Описание взаимодействия частей Можно создать схему последовательностей, чтобы показать, как части взаимодействуют друг с другом в ответ на сообщение, поступающее в родительский компонент. Можно использовать эти схемы, чтобы проанализировать существующий компонент и создать новый. При конструировании компонента можно создавать схемы последовательностей, даже если еще не решено, какие части будут входить в его состав. Схемы последовательностей можно использовать, чтобы поэкспериментировать с различными частями, требуемыми интерфейсами и последовательностями сообщений. Создайте схемы последовательностей для наиболее часто встречающихся и наиболее важных входящих сообщений. После этого можно создавать части в компоненте, которые соответствуют выбранным линиям жизни. Используйте схемы последовательностей, чтобы оценить, как функционирование системы распределяется между разными компонентами. Если слишком много функций делегировано одной части, вероятно, возникнут сложности с обновлением приложения. При равномерном распределении функций это маловероятно. Если функции, напротив, распределены между большим числом компонентов, между которыми существует много взаимодействий, производительность системы может снизиться, ее понимание будет затруднено. Создание схемы последовательностей, показывающей взаимодействие частей Создайте новую схему последовательностей. Создайте линию жизни для внешнего компонента, пользователя, устройства или другого субъекта (1), отправляющего сообщения этому компоненту. Свойству Субъект данной линии жизни можно задать значение true, чтобы указать, что это внешнее свойство рассматриваемого компонента. Над линией жизни отображается контурограмма. Создайте линию жизни для предоставленного интерфейса (2) этого компонента, которому выбранный субъект отправляет сообщения. Создайте линию жизни для каждой части (3) компонента. Создайте линию жизни для каждого требуемого интерфейса (4) компонента. Создайте сообщения от внешнего субъекта (5). Покажите, как сообщение передается частям и как они взаимодействуют в ответ на него. При необходимости покажите сообщения, отправляемые требуемому интерфейсу (6). Не показывайте никаких подробностей в области выполнения сообщения. Компонент — это больше, чем его части? В некоторых случаях компонент — это не больше, чем имя, присвоенное коллекции частей. Всю работу выполняют части, и во время выполнения нет ни кода, ни других артефактов, которые представляют компонент. Это можно указать в модели, задав свойство Является неявно создаваемым экземпляром компонента. В этом случае все интерфейсы компонента должны находиться в портах и иметь делегирования во внутренние части. Описание процесса внутри каждой части . Используйте "Принять действие события" (1), чтобы показать, что входящее сообщение начинает новый поток. Используйте узлы объекта и закрепления ввода или вывода, чтобы показать поток сведений и показать, где хранятся сведения. В этом примере узел объекта (2) показывает элементы, буферизованные между двумя потоками. Определение данных и классов UML-схему классов можно использовать, чтобы подробно описать содержимое следующих элементов: интерфейсов компонентов; данных, переданных в параметрах операций в интерфейсах; данных, сохраненных в компонентах, например как показано в потоках объектов на схемах активности; общих зависимостей между компонентами. Можно использовать схему компонентов только для того, чтобы показать основные части конструкции и взаимозависимости между ними. Чтобы создать зависимость, воспользуйтесь инструментом Зависимость. Это означает, что конструкция одного компонента зависит от конструкции другого. Наиболее распространены следующие виды зависимостей. Один компонент вызывает код внутри другого. Один компонент создает экземпляр класса, определенного внутри другого класса. Один компонент использует сведения, созданные другим. Можно использовать имя стрелки зависимости, чтобы обозначить конкретный вид использования. Чтобы задать имя, щелкните стрелку правой кнопкой мыши, затем щелкните Свойства и задайте значение в поле Имя в окне свойств. Чтение схем компонентов В следующей таблице описаны элементы, которые можно использовать на схеме компонентов, и их основные свойства.
|