Основы UML

Печать
Рейтинг пользователей: / 8
ХудшийЛучший 

Основы UML

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

Метамодель – это способ описания языка, на котором описывается модель.

Нотации визуального проектирования применяются довольно давно. Они играют основную роль для взаимопонимания. Хорошая диаграмма часто помогает обменяться идеями о проекте, особенно когда вы хотите избежать излишне подробного объяснения. Диаграммы также помогают понять и программную систему и бизнес-план.

Создатели UML стремились предоставить пользователям стандартный визуальный язык, позволяющий разрабатывать понятные модели и обмениваться ими. UML не зависит от конкретных языков программирования и процессов разработки и применяется для:

·         визуализации программной системы набором строго определенных символов. Разработчик приложения может однозначно интерпретировать UML-модель, созданную другим разработчиком;

·         описания спецификации информационной системы. UML помогает строить точные, однозначные и полные модели;

·         конструирования моделей программной системы, которые могут напрямую преобразовываться в текст на различных языках программирования;

·         документирования моделей программной системы, выражая требования к системе на стадиях разработки и развертывания.

Основные черты UML:

·         простой и выразительный язык визуального моделирования;

·         состоит из набора нотаций и правил моделирования программных систем различной степени сложности;

·         дает возможность создавать простые, хорошо документированные и легкие для понимания модели ПО;

·         не зависит как от языка программирования, так и от платформы.

Когда группа разработчиков пытается в чем-то разобраться, диаграммы помогают установлению взаимопонимания и распространению такого поминания в команде. Диаграммы не заменяют текстовые языки программирования, но способны оказать существенную помощь.

Наряду с графическими элементами значимость UML основана на его широком распространении и стандартизации в рамках сообщества разработчиков, применяющих объектно-ориентированные технологии.

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


 Способы применения UML

При разработке ПО UML применяется в различных режимах. Можно выделить три основные:

·         режим создания эскизов;

·         режим проектирования;

·         режим программирования.

Наиболее важный – режим использования UML для создания эскиза. В этом режиме разработчики используют UML для обмена информацией о различных аспектах системы.

UML можно использовать для прямой и обратной разработки. При прямой разработке (forward-engineering) диаграммы рисуются до написания кода, а при обратной разработке (reverse-engineering) диаграммы строятся на основе исходно кода, чтобы лучше понять его.

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

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

Напортив, язык UML как средство проектирования нацелен на полноту. Такая модель должна быть полной в части заложенных проектных решений, а программист должен иметь возможность следовать им прямо и не особо задумываясь.

Применение UML в режиме программирования предполагает активное использование инструментальных средств для генерации исходного кода на основе UML диаграмм. Очевидно, что такое применение UML требует особенно сложных инструментов. На сегодняшний день это режим ограничивается генерацией заготовок для основных классов приложения.


Модель и ее элементы

Модель UML это конечное множество сущностей и отношений между ними. Сущности и отношения модели это экземпляры метаклассов метамодели. Метакласс – это класс, экземплярами которого являются классы.

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

Сущности

Для удобства обзора сущности в UML можно подразделить на четыре группы:

·         структурные;

·         поведенческие;

·         группирующие;

·         аннотационные.

К структурным сущностям относят следующие:

·         Класс – описание множества объектов с общими атрибутами и операциями.

·         Интерфейс – множество операций, которое определяет набор услуг (службу), предоставляемых классом или компонентом.

·         Действующее лицо, актер – сущность, находящаяся вне моделируемой системы и непосредственно взаимодействующая с ней. Им может быть как человек, как и другая система.

·         Вариант использования, прецедент – описание последовательности производимых системой действий, доставляющей значимый для некоторого действующего лица результат.

·         Компонент – физически заменяемый артефакт, реализующий некоторый набор интерфейсов.

·         Узел – физический вычислительный ресурс.

Приведенная классификация не является исчерпывающей. У каждой из этих сущностей есть различные частные случаи и вариации.

Основных поведенческих сущностей всего две: состояние и деятельность.

·         Состояние – период в жизненном цикле объекта, в котором объект удовлетворяет некоторому условию, выполняет деятельность или ожидает события.

·         Деятельность – состояние, в котором выполняется работа, а не просто пассивно ожидается наступление события.

Группирующая сущность в UML одна – пакет.

Пакет – группа элементов модели (в том числе пакетов).

Аннотационная сущность тоже одна – примечание – зато в нее можно поместить все что угодно, так как содержание примечания UML не ограничивает.

Ниже в таблице приведена стандартная нотация в минимальном варианте для упомянутых сущностей.

Отношения

В UML используются четыре основных типа отношений:

·         зависимость;

·         ассоциация;

·         обобщение;

·         реализация.

Зависимость – это наиболее общий тип отношения между двумя сущностями. Отношение зависимости указывает на то, что изменение независимой сущности каким-то образом влияет на зависимую сущность. Графически отношение зависимости изображается в виде пунктирной стрелки, направленной от независимой сущности к зависимой. Как правило, семантика конкретной зависимости уточняется в модели с помощью дополнительной информации. Например, зависимость со стереотипом «use» означает, что зависимая сущность использует (скажем, вызывает операцию) независимую сущность.

Ассоциация – это наиболее часто используемый тип отношения между сущностями. Отношение ассоциации имеет место, если одна сущность непосредственно связана с другой (или с другими). Ассоциация может быть не только бинарной. Графически ассоциация изображается в виде сплошной линии с различными дополнениями, соединяющей связанные сущности. На программном уровне непосредственная связь может быть реализована различным образом, главное, что ассоциированные сущности знают друг о друге. Например, отношение часть – целое является частным случаем ассоциации и называется отношением агрегации.

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

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


Диаграммы

Помимо сущностей и отношений, в модели должна быть какая-то структура, которая бы помогала ее составлению и пониманию.

Диаграммы UML и есть та основная накладываемая на модель структура, которая облегчает создание и использование модели.

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


Классификация диаграмм

Определены следующие канонические типы диаграмм:

·         диаграмма использования;

·         диаграмма классов;

·         диаграмма объектов;

·         диаграмма состояний;

·         диаграмма деятельности;

·         диаграмма последовательности;

·         диаграмма кооперации;

·         диаграмма компонентов;

·         диаграмма размещения;

·         диаграмма пакетов.

Канонические диаграммы отнюдь не образуют полного “ортогонального” набора: они пересекаются как по включенным в них средствам, так и по области применения. Более того, некоторые из них являются частными случаями других, есть просто семантические эквивалентные пары, можно привести примеры допустимых диаграмм, для которых затруднительно указать однозначно, к какому именно из канонических типов диаграмма относится.

Сказанное можно проиллюстрировать условной классификацией диаграмм, приведенной на рисунке:


Диаграмма классов

Диаграмма классов описывает типы объектов системы и различного рода статические отношения, которые существуют между ними. На диаграммах классов отображается также свойства классов, операции классов и ограничения, которые накладываются на связи между объектами.

Прямоугольники на диаграмме представляют классы и разделены на три части: имя класса, его атрибуты и операции. На диаграммах так же задаются связи между классами: ассоциация и обобщение.

Основные элементы нотации, применяемые на диаграмме классов, показаны на рисунке:

Свойства

Свойства представляют структурную функциональность класса. В первом приближении можно рассматривать свойства как поля класса. Свойства представляют единое понятие, воплощающееся в двух различных сущностях: в атрибутах и в ассоциациях.

Атрибуты

Атрибуты описывают свойства в виде строки текста внутри прямоугольников класса. Полная форма атрибута:

видимость имя: тип кратность = значение по умолчанию {строка свойств}

Например:

+ наименование: String = “не задано” {readOnly}

Обязательным является только имя атрибута.

·         Метка видимость обозначает, относится ли атрибут к открытым (+) (public) или закрытым (-) (private).

·         Имя атрибута – способ ссылки класса на атрибут – приблизительно соответствует имени поля в языке программирования.

·         Тип атрибута накладывает ограничение на вид объекта, который может быть размещен в атрибуте. Можно считать его аналогом типа в языке программирования.

Ассоциации

Другая часть свойств – это ассоциации. Ассоциация это непрерывная линия между двумя классами, направленная от исходного класса к целевому. Имя свойства (вместе с кратностью) располагается на целевом конце.

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

Кратность

Кратность обозначает количество объектов, которые могут заполнять данное свойство. Чаще всего используются следующие кратности:

·         1 (Заказ может предоставить только один клиент.)

·         0..1 (Корпоративный клиент может иметь, а может не иметь единственного торгового представителя.)

·         * (Клиент может разместить ноль или более заказов.)

Операции

Операции представляют собой действия, реализуемые некоторым классом. Существует очевидное соответствие между операциями и методами класса. Полный синтаксис операции в языке UML выглядит следующим образом:

видимость имя (список параметров) : возвращаемый тип {строка свойств}

Параметры в списке параметров обозначаются таким же образом, как и атрибуты.

Например, в счете операция может выглядеть так:

+ balanceOn (date: Date) : Money

Обобщения

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

Важным принципом эффективного использования наследования является замещаемость. Это означает, что если программа рассчитана на использование класса Клиент, то она может работать с любыми его подтипами (это является «Принципом подстановки Лискоу»).

Зависимости

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

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


Диаграмма прецедентов (вариантов использования)

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

Содержимое прецедентов

Не существует стандартного способа описания содержимого прецедента; в различных случаях применяются различные форматы. Можно порекомендовать следующий стиль описания:

Подпись: Покупка товара  Главный успешный сценарий.  1.	Покупатель просматривает каталог и выбирает товары для покупки.  2.	Покупатель оценивает стоимость всех товаров.  3.	Покупатель вводит информацию, необходимую для доставки товара.   4.	Система предоставляет полную информацию о цене товара и его доставке.  5.	Покупатель вводит информацию о кредитной карточке.  6.	Система осуществляет авторизацию счета покупателя.  7.	Система подтверждает оплату товаров немедленно.  8.	Система посылает подтверждение оплаты товаров по адресу электронной почты клиента.  Расширения.  	3а.	Клиент является постоянным покупателем.  	.1:	Система предоставляет информацию о текущей покупке и её цене, а также информацию о счете.  	.2:	Покупатель может согласиться или изменить значения по умолчанию, затем возвращается к шагу 6 главного сценария.  	6а.	Система не подтверждает авторизацию счета.  	.1	Пользователь может повторить ввод информации о кредитной карте или закончить сеанс.

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

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

Диаграмма прецедентов (вариантов использования) – это наиболее общее представление функционального назначения системы. Диаграмма прецедентов призвана ответить на главный вопрос моделирования: что делает система во внешнем мире?

Диаграмма прецедентов показывает актеров, прецеденты и отношения между ними:

·         Какие актеры выполняют тот или иной прецедент

·         Какие прецеденты включают другие прецеденты

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

Основные элементы нотации, применяемые на диаграмме прецедентов, показаны на рисунке:


Диаграмма объектов

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

На диаграмме объектов применяют один основной тип сущностей: объекты (экземпляры классов), между которыми указываются конкретные связи (экземпляры ассоциаций).

Основные элементы нотации, применяемые на диаграмме объектов, показаны на рисунке:


Диаграмма деятельности

Диаграмма деятельности – это, фактически, блок-схема алгоритма, в которой модернизированы обозначения.

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

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


Диаграмма последовательности

Диаграмма последовательности – это способ описать поведение системы “на примерах”. Фактически, диаграмма последовательности это запись протокола конкретного сеанса работы системы (или фрагмента такого протокола). В объектно-ориентированном программировании самым существенным во время выполнения является посылка сообщений взаимодействующими объектами. Именно последовательность посылки сообщений отображается на данной диаграмме.

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

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

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


Диаграмма размещения

Диаграмма размещения представляет физическое расположение системы, показывая, на каком физическом оборудовании запускается та или иная составляющая программного обеспечения. На рисунке показаны основные элементы нотации, применяемые на диаграмме размещения.


Диаграмма пакетов

Классы составляют структурный костяк объектно-ориентированной системы. Хотя они исключительно полезны, но нужно нечто большее для структурирования больших систем, которые могут состоять из сотен классов.

Пакет – это инструмент группирования, который позволяет взять любую конструкцию UML и объединить её элементы в единицы высокого уровня.

В терминах программирования на C# пакеты UML соответствуют пространствам имен.

На диаграммах пакеты изображены в виде папок с закладками. Изображение содержимого пакета с помощью значков классов позволяет показать все особенности класса, вплоть до изображения диаграммы классов внутри пакета.

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

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

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

Допустим, что вы хотите предоставить некоторый пользовательский интерфейс (UI) выключателей для включения и выключения некоторого объекта. Мы хотим, чтобы он работал с различными устройствами, такими как обогреватели (heaters) или лампы (lights). Выключатели UI должны вызывать методы обогревателя, но мы не хотим, чтобы выключатели зависели от обогревателей. Мы можем избежать этой зависимости, определяя в пакете выключателей интерфейс, который затем реализуется каждым классом, работающим с этим выключателем, как показано на рисунке ниже. Здесь представлен пример шаблона Разделенный интерфейс.