Основные конструкции языка uml
Поскольку использование объектно-ориентированного подхода особое значение имеет при разработке сложных программных продуктов, модели предметной области, которые приходится строить в этих случаях, тоже будут сложны. Удержать в голове эту модель целиком или по частям разработчик (или коллектив разработчиков) обычно не в состоянии. Поэтому особое значение при объектно-ориентированном подходе имеют средства, позволяющие визуализировать, сохранять и документировать принимаемые решения. Одним из таких средств является унифицированный язык моделирования UML. Разработка системы средствами UML происходит в виде построения набора диаграмм, позволяющих описать определенные части моделируемой реальности в определенных аспектах.
В данном разделе мы рассмотрим основные конструкции языка UML. Наше обсуждение ни в коей мере не будет претендовать на полноту изложения. Мы лишь рассмотрим некоторые типы диаграмм и отражаемых на них элементов. В основном мы ограничимся отдельными способами представления структурных отношений между классами, интерфейсами и объектами (статический аспект) и их поведения (динамический аспект) в логической структуре проекта, не затрагивая таких вопросов моделирования, как выработка требований к системе и физическая реализация.
Диаграмма классов
Основными элементами, отображаемыми на диаграмме классов, являются классы, интерфейсы и отношения между ними.
Графическое изображение класса представлено на рис. 6.1.
Каждый класс должен иметь имя. На некоторых значках классов полезно перечислять несколько атрибутов и операций класса. "На некоторых", потому что для большинства тривиальных классов это не нужно. Если мы не хотим видеть на диаграмме атрибуты и операции класса, мы удаляем разделяющие черты и пишем только имя класса.
Рис. 6.1. Значок Рис. 6.2. Статические Рис. 6.3. Утилита
класса члены класса
Атрибут может обозначаться именем, также могут быть указаны тип (класс), видимость, кратность и значение по умолчанию в соответствии со следующим синтаксисом:
видимость имя [кратность] : тип = значение_по_умолчанию.
Видимость обозначается путем добавления в качестве префикса к имени следующих символов: открытый(+), защищенный (#), закрытый(–).
Кратность (количество элементов указанного типа, составляющих атрибут) показывается в виде последовательности разделенных запятой спецификаций интервалов в формате: нижняя граница .. верхняя граница и конкретных значений. Для обозначения неограниченного количества используется символ *. Например:
1 в точности один;
* ноль или больше;
0 .. * ноль или больше;
1 .. * один или больше;
3 .. 7 указанный интервал;
1 .. 3, 7 указанный интервал или точное число.
Приведем примеры описания атрибутов:
А только имя;
+А : С видимость, имя и тип;
А[10] : С имя, кратность и тип;
А : С = Е имя, тип и значение по умолчанию.
Операции обычно изображаются внутри значка класса только своим именем. Возможно также указывать дополнительные элементы в формате: видимость имя (формальные_параметры) : тип_возвращаемого_значения.
Формальные параметры записываются в формате:
вид имя : тип = значение_по_умолчанию,
где вид принимает одно из следующих значений:
in – входной параметр (значение по умолчанию);
out – выходной параметр;
inout – смешанный, т.е. и входной, и выходной.
Если параметр помечен как входной, то функция не может изменять его значения, но может его использовать (передача параметров по значению); если параметр помечен как выходной, то функция не может использовать его значение, но может присвоить ему некоторое значение; наконец, если параметр помечен как смешанный, то функция может и читать его значение, и изменять (передача параметров по ссылке).
Приведем примеры описания операций:
display ( ) – только имя;
display ( ): bool – имя и тип возвращаемого значения;
+set (n: Name, s: String) – видимость, имя и формальные параметры.
Атрибуты и операции класса (статические члены) изображаются подчеркнутыми. Пример на рис. 6.2 показывает изображение класса Data (см. п. 4.6).
Утилита изображается обычным значком класса со стереотипом "utility" (рис. 6.3). Добавление к стандартному элементу языка стереотипа позволяет приспособить данный элемента для решения специальной проблемы.
Интерфейс на диаграмме классов можно изобразить двумя способами: развернутым и сокращенным. В случае развернутого способа интерфейс изображается на диаграмме как класс со стереотипом "interface" и без секции атрибутов (рис. 6.4). Сокращенное изображение интерфейса представляет небольшой кружок с именем интерфейса возле него (рис. 6.5).
Рис. 6.4. Развернутое Рис. 6.5. Сокращенное
изображение интерфейса изображение интерфейса
Классы редко бывают изолированными; они вступают в отношения друг с другом.
Значок ассоциации изображается в виде линии, соединяющей два класса (рис. 6.6). При изображении ассоциации ей можно сопоставить текстовую пометку, документирующую имя этой связи или подсказывающую ее роль. Ассоциации часто отмечаются существительными, например "Место работы", описывающими природу связи. К значку также можно добавить роли, которые классы играют в ассоциации. Одна пара классов может иметь более одной ассоциативной связи. Возле значка ассоциации можно указать ее кратность.
Рис. 6.6. Ассоциация Рис. 6.7. Зависимость
Указывая кратность на одном конце, показывают, что на этом конце именно столько объектов должно соответствовать каждому объекту на другом конце. Если кратность явно не указана, то подразумевается, что она не определена.
На рис. 6.6 изображена ассоциация "Компания" – "Человек", которой дано имя "Место работы". Классы, участвующие в ней, играют роли "Работодатель" и "Работник" соответственно.
Отношение зависимости изображается пунктирной линией со стрелкой, направленной от клиента к серверу (рис. 6.7). Стереотип "friend" на линии зависимости указывает, что клиент является дружественным классом для сервера.
Значок обобщения (наследования) включает большую незакрашенную стрелку, которая указывает от подкласса к суперклассу (рис. 6.8). Место классов в наследственной иерархии можно уточнить следующим образом. Имена абстрактных классов указываются курсивом. К имени базового класса добавляется свойство root, а к имени листового класса – свойство leaf. Аналогично, имена чисто виртуальных функций-членов указываются курсивом, а к имени операции, которая не может быть виртуальной, добавляется свойство leaf.
Пример. На рис. 6.8 показана наследственная иерархия, связанная с геометрическими фигурами (см. п. 4.3.1). Абстрактный класс Shape отмечен как базовый класс, имеющий чисто виртуальные функции draw, rotate и листовую функцию get_center. Функция draw в протоколе класса Circle является полиморфной. Класс SolidCircle объявлен как листовой.
Значок агрегации – линия с добавлением незакрашенного ромба на конце, обозначающем агрегат (рис. 6.9). Экземпляры класса на другом конце стрелки будут частями экземпляров класса-агрегата. Отношение композиции обозначается линией с закрашенным ромбом на конце (рис. 6.10).
Рис. 6.8. Обобщение
Рис. 6.9. Агрегация Рис. 6.10. Композиция
Параметризованный класс изображается значком обычного класса с пунктирным прямоугольником в правом верхнем углу, в котором указаны параметры (рис. 6.11). Моделировать инстанцирование можно двумя способами. Во-первых, можно явным образом определить зависимость со стереотипом "bind", показывающую, что источник инстанцирует целевой шаблон с заданными фактическими параметрами. Во-вторых моделировать можно неявно, для чего требуется объявить класс, имя которого обеспечивает инстанцирование. Пример использования данных способов представлен на рис. 6.11–6.12 для стека контроллеров, рассмотренного в п. 4.5.
Рис. 6.11. Явное связывание Рис. 6.12. Неявное связывание
Пример. На рис. 6.13 представлена система классов, служащая для моделирования процесса обслуживания системы управления климатом в теплице. Класс Plan включает правила управления климатом и имеет операцию execute (выполнить). Имеется ассоциация между этим классом и классом Controller (контроллер, управляющий климатом): экземпляры класса Plan задают климат, который должны поддерживать экземпляры класса Controller.
Эта диаграмма также показывает, что класс Controller является агрегатом: его экземпляры содержат в точности по одному экземпляру классов Heater (нагреватель) и Cooler (охлаждающее устройство), и любое число экземпляров класса Light (лампочка). Оба класса Heater и Cooler являются подклассами абстрактного запускающего процесс класса Actuator, который предоставляет протоколы startUp и shutDown (начать и прекратить соответственно) и использует класс Temperature.
Рис. 6.13. Классы для описания процесса обслуживания системы управления климатом
Связь интерфейса с реализующим его элементом можно графически представить двумя способами. Простая форма позволяет изобразить отношения между интерфейсом и реализующим его классом в виде кружка с одной стороны класса (рис. 4.3–4.4). Если интерфейс представлен в расширенной форме, то отношение реализации изображают в виде пунктирной линии с большой незакрашенной стрелкой, направленной в сторону интерфейса (рис. 6.14). Зависимость между классом и интерфейсом показывается аналогично зависимости между классами.
Рис. 6.14. Отношения между классами и интерфейсом
Диаграмма объектов
Диаграмма объектов показывает существующие объекты и их связи в некоторый момент времени.
Диаграмма объектов может рассматриваться как прототип: она представляет отношения, которые могут возникнуть у данного множества экземпляров классов, безотносительно к тому, какие конкретно экземпляры участвуют в этом взаимодействии.
Объект на диаграмме объектов изображается значком, показанным на рис. 6.15. Он совпадает со значком класса, но имя объекта подчеркивается. Горизонтальная линия разделяет текст внутри значка объекта на две части: имя объекта и его атрибуты.
Имя объекта следует синтаксису для атрибутов и может быть записано в одной из следующих форм:
Рис. 6.15. Значок объекта Рис. 6.16. Значок связи
А – только имя объекта;
: С – только класс объектов (анонимный экземпляр);
А : – экземпляр, класс которого пока неизвестен;
А : С – имя объекта и класса.
Каждый значок без имени объекта обозначает на диаграмме отдельный анонимный объект.
Объекты взаимодействуют с другими объектами через связи, которые изображаются на диаграмме прямыми линиями (см. рис 6.16).
На значках объектов бывает полезно указать несколько их атрибутов. Синтаксис атрибутов совпадает с синтаксисом атрибутов класса и позволяет указать их текущее значение (см. рис 6.17). Имена атрибутов объектов должны соответствовать атрибутам, определенным в классе объекта, или в любом из его суперклассов.
На рис. 6.17 приведен пример диаграммы объектов, соответствующий диаграмме классов на рис. 6.6.
Рис. 6.17. Диаграмма объектов
Диаграммы взаимодействий
На диаграммах взаимодействий отражаются множество объектов и отношения между ними, включая сообщения, которыми они обмениваются. К диаграммам взаимодействий относятся диаграммы последовательностей и диаграммы кооперации.
На диаграммах последовательностей внимание акцентируется прежде всего на временной упорядоченности сообщений. Преимущество диаграммы последовательностей в том, что на ней легче читается порядок посылки сообщений.
Диаграмма последовательностей внешне напоминает таблицу (рис. 6.18–6.19). Изображения объектов на диаграмме последовательностей помещают в верхней ее строке. Обычно инициирующий взаимодействие объект размещается слева, а остальные правее (тем дальше, чем более подчиненным является объект).
Отправления сообщений (вызовы операций) показываются горизонтальными стрелками. Линия, обозначающая посылку сообщения, проводится от вертикали клиента к вертикали сервера. Первое сообщение показывается на самом высоком уровне, второе – ниже и т.д. Возвращаемое значение можно показать пунктирной стрелкой от сервера к клиенту.
Вызов операции обозначается ее именем, кроме того, здесь могут быть приведены возвращаемое значение и фактические параметры, подходящие к сигнатуре операции:
N ( ) – только имя операции;
r := N (a, c) – возвращаемое значение (r), имя и фактические параметры операции – a и c.
Пример. Диаграмма последовательностей приведена на рис. 6.18. На диаграмме отражено сотрудничество трех объектов. Сценарий начинается с вызова объектом А операции f1 над объектом В. Это порождает вызов объектом В операции f2 над объектом С, что потребует вызова объектом С операции f3 над собой. Когда эта операция будет выполнена, объект В возвратит значение r объекту А, который затем вызывает операцию f4 над объектом С.
Рис. 6.18. Диаграмма последовательностей Рис. 6.19. Расширенная диаграмма
последовательностей
Диаграммы последовательностей характеризуются двумя особенностями, отличающими их от диаграмм коопераций.
Во-первых, на них показана линия жизни объекта. Это вертикальная пунктирная линия, отражающая существование объекта во времени. Большая часть объектов, представленных на диаграмме взаимодействий, существует на протяжении всего взаимодействия, поэтому их изображают в верхней части диаграммы, а их линии жизни прорисованы сверху до низу. Объекты могут создаваться и во время взаимодействий. Линии жизни таких объектов начинаются с получения сообщения со стереотипом "create". Объекты могут также уничтожаться во время взаимодействий; в таком случае их линии жизни заканчиваются получением сообщения со стереотипом "destroy", а в качестве визуального образа используется большая буква Х.
Во-вторых, на этих диаграммам может быть изображен фокус управления. Он изображается в виде вытянутого прямоугольника, показывающего промежуток времени, в течение которого объект выполняет какое-либо действие, непосредственно или с помощью подчиненной процедуры (рис. 6.19). Верхняя грань прямоугольника выравнивается по временной оси с моментом начала действия, нижняя – с моментом его завершения. Вложенность фокуса управления, вызванную рекурсией (т.е. обращением к собственной операции) или обратным вызовом со стороны другого объекта, можно показать, расположив другой фокус управления чуть правее своего родителя.
Рис. 6.19 показан пример, аналогичный предыдущему, в котором, однако, объект В создается и уничтожается во время взаимодействия.
Диаграмма кооперации акцентирует внимание на структурной организации объектов, принимающих и отправляющих сообщения.
На диаграмме изображаются объекты и связи между ними, как на диаграмме объектов. Рядом с соответствующей связью на диаграмме можно записать набор сообщений. Каждое сообщение состоит из следующих трех элементов:
– направление вызова;
– вызов операции;
– порядковый номер.
Направление сообщения показывается стрелкой, указывающей на объект-сервер.
Вызов операции обозначается с использованием того же самого синтаксиса, что и на диаграмме кооперации.
Порядковый номер показывает относительный порядок посылки сообщений. Сообщение с меньшим порядковым номером посылается до сообщения с большим номером. Нумерация начинается с единицы и добавляется как префикс к вызову операции. Для отображения вложенных сообщений используется следующая нотация: 1 – первое сообщение; 1.1 – первое сообщение, вложенное в сообщение 1; 1.2 – второе сообщение, вложенное в сообщение 1, и т.д.
Для описания связи одного объекта с другим к дальней концевой точке этой связи можно присоединить один из следующих стереотипов пути:
"association" – соответствующий объект видим для ассоциации;
"self" – соответствующий объект видим, потому что является диспетчером для операции (обозначение связи объекта с самим собой);
"global" – соответствующий объект видим, т.к. находится в объемлющей области видимости;
"local" – соответствующий объект видим, поскольку находится в локальной области действия операции;
"parameter" – соответствующий объект видим, т.к. является параметром операции.
Пример. Диаграмма кооперации, соответствующая диаграмме взаимодействий с рис. 6.19, показана на рис. 6.20. Дополнительная информация на диаграмме отражает тот факт, что объект С является глобальным по отношению к остальным объектам.
Рис. 6.20. Диаграмма кооперации
Чаще всего приходится моделировать неветвящиеся последовательные потоки управления. Однако можно моделировать и более сложные потоки, содержащие итерации и ветвления.
Итерация представляет собой повторяющуюся последовательность сообщений. Ее изображение приведено на рис. 6.21: перед номером сообщения в последовательности ставится выражение итерации, например *[i := 1 .. n] (или просто *, если надо обозначить итерацию без дальнейшей детализации). Итерация показывает, что сообщение (и все вложенные в него сообщения) будет повторяться в соответствии со значением заданного выражения.
Рис. 6.21. Итерации Рис. 6.22. Условие
Условие представляет собой сообщение, выполнение которого зависит от результатов вычисления некоторого булевского выражения. Для моделирования условия перед порядковым номером сообщения ставится выражение, например [х>0] (рис. 6.22). У всех альтернативных ветвей будет один и тот же порядковый номер, но условия на каждой ветви должны быть заданы так, чтобы два из них не выполнялись одновременно (не перекрывались).
Диаграмма состояний
Диаграмма состояний включает:
–состояния;
– переходы вместе с ассоциированными событиями и действиями.
Состоянием в контексте диаграммы состояний будем называть ситуацию в жизни объекта, на протяжении которой он удовлетворяет некоторому условию, осуществляет определенную деятельность или ожидает какого-то события.
Событием в контексте диаграммы состояний будем называть любое происшествие, которое может быть причиной изменения состояния системы.
Деятельность – это продолжающийся во времени неатомарный шаг вычислений при реализации поведения объекта. Действие – атомарное вычисление, которое приводит к изменению состояния системы или возврату значения. Действие может заключаться в вызове операции, создании или уничтожении объекта либо в простом вычислении – скажем, значения выражения. Поскольку действие атомарно, оно не может быть прервано другим событием, и, следовательно, выполняется до полного завершения. В отличие деятельности, которая может быть прервана другим событием.
Обозначение отдельного состояния приведено на рис. 6.23. Каждое состояние должно иметь имя, указываемое на значке.
Рис. 6.23. Значок Рис. 6.24. Значки Рис. 6.25. Состояние
состояния перехода "Обогрев"
Изменение состояний осуществляется в результате перехода. Переход – это отношение между двумя состояниями, показывающее, что объект, находящийся в первом состоянии, должен выполнить определенные действия и перейти во второе состояние, как только произойдет указанное событие и будут удовлетворены указанные условия.
Говорят, что при таком изменении состояния переход срабатывает. Пока переход не сработал, объект находится в исходном состоянии; после срабатывания он находится в целевом состоянии. Например, Обогреватель может перейти из состояния Ожидание в состояние Активация при возникновении события tooCold (слишкомХолодно) с параметром desiredTemp (желаемаяТемпература).
Переход определяют пять элементов:
исходное состояние – состояние, из которого происходит переход; если объект находится в исходном состоянии, то исходящий переход может сработать тогда, когда объект получит событие-триггер, инициирующее этот переход, причем должно быть выполнено сторожевое условие (если оно задано);
событие-триггер – событие, при получении которого объектом, находящимся в исходном состоянии, может сработать переход (при этом должно быть выполнено сторожевое условие);
сторожевое условие – булевское выражение, которое вычисляется при получении события-триггера; если значение истинно, то переходу разрешено сработать, если ложно – переход не срабатывает; если при этом не задано никакого другого перехода, инициируемого тем же самым событием, то событие теряется;
действие – атомарное вычисление, которое может непосредственно воздействовать на рассматриваемый объект или оказать косвенное воздействие на другие объекты, находящиеся в области видимости;
целевое состояние – состояние, которое становится активным после завершения перехода; состояние может иметь переход само в себя.
Переход на диаграмме состояний изображается линией со стрелкой, направленной от исходного состояния к целевому. Рядом с линией указываются событие, вызвавшее переход, условие, при выполнении которого происходит переход, и ассоциированные с переходом действия (рис. 6.24).
На каждой диаграмме состояний должно присутствовать ровно одно стартовое состояние: оно обозначается немаркированным переходом в него из специального значка, изображаемого в виде закрашенного кружка (см. рис. 6.24). Иногда бывает нужно указать также конечное состояние, которое обозначают, рисуя немаркированный переход от него к специальному значку, изображаемому как кружок с закрашенной серединой (см. рис. 6.24).
Допускаются "переходы без события" – нетриггерные переходы. В этом случае переход совершается сразу после завершения действия, связанного с состоянием. Если переход условный, он состоится только в случае, если условие выполнено.
На значках состояний можно указывать некоторые действия, деятельности и внутренние переходы.
Можно назначить выполнение некоторого действия на входе или выходе из состояния. Для этого используются ключевые слова entry и exit (вход и выход). Например, на рис. 6.25 приведен значок состояния "Обогрев" объекта, управляющего температурой. При каждом входе в данное состояние выполняется операции StartUp (запустить обогреватель), а при каждом при выходе из состояния – операции ShutDown (отключить обогреватель).
Когда объект находится в некотором состоянии, он обычно бездействует и ожидает возникновения какого-либо события. Но иногда приходится моделировать и ситуацию непрерывно продолжающейся деятельности. Находясь в таком состоянии, объект чем-нибудь занимается до тех пор, пока эта деятельность не будет прервана событием. Ключевое слово do служит для явных указаний: "Начать деятельность при входе в состояние (после того, как было отработано действие при входе) и окончить при выходе из него". Например, пока объект находится в состоянии "Обогрев", осуществляется деятельность Heating (рис. 6.25). Допустимо специфицировать и последовательность действий, которые отделяются друг от друга точкой с запятой, например
dо / ор1(а); ор2(b); ор3(с).
Единичное действие не может быть прервано, но к последовательности действий это не относится. Между выполнением соседних действий возможно обрабатывать события, и не исключено, что в результате этого произойдет выход из состояния.
В любой моделируемой ситуации бывает необходимо одни события распознавать, а другие игнорировать. Между тем иногда необходимо распознать событие, но отложить его обработку на будущее. Такое поведение специфицируется с помощью отложенных событий. Отложенное событие – это список событий, возникновение которых в конкретном состоянии отложено до перехода в состояние, где эти события не являются отложенными. В этот момент события могут быть обработаны и инициировать те или иные переходы, как будто они произошли только что. На рис. 6.25 показано, что событие описывается как отложенное путем связывания с ним специального действия defer (отложить). Находясь в состоянии "Обогрев", объект, управляющий температурой, может отложить обработку сигнала самопроверки, посылаемого некоторым внешним объектом, отвечающим за периодическое обслуживание.
Находясь в некотором состоянии, объект может получить события, которые желательно обработать, не покидая состояния. Такая обработка называется внутренним переходом. Между внутренним переходом и переходом в себя имеется некоторое различие. При переходе в себя событие инициирует переход, происходит выход из данного состояния и выполняется действие при выходе (exit). Затем, поскольку при переходе в себя происходит выход из состояния и повторный вход в него же, выполняется действие, ассоциированное с переходом, и, кроме того, действие при входе в состояние (entry). Предположим, однако, что необходимо обработать событие, не возбуждая действия при входе и выходе. Для этого в значок, обозначающий состояние, можно поместить внутренний переход в виде
событие / действие.
Если объект находится в таком состоянии и происходит указанное событие, то соответствующее действие выполняется без выхода и повторного входа в состояние, т.е. событие обрабатывается, не возбуждая действий при входе и выходе.
Пример. На рис. 6.26 изображена диаграмма состояний для класса Controller, служащего для управления температурой и освещением в системе управления климатом теплицы.
Мы видим, что все объекты этого класса начинают свою жизнь в начальном состоянии "Ожидание"; затем они изменяют свое состояние по событию "Ввод климатического задания", для которого не предполагается явных действий. Дальше динамическое поведение этого класса состоит в переключении между состояниями "День" и "Ночь"; оно определяется событиями "Восход" и "Закат" соответственно; с этими событиями связаны действия по изменению освещения. В обоих состояниях событие понижения или повышения температуры в теплице вызывает обратную реакцию – операцию "Изменить температуру". Мы возвращаемся в состояние "Ожидание", когда поступит событие "Отмена климатического задания".
Рис. 6.26. Диаграмма состояний для объекта класса Controller
На диаграмме состояний возможно показать подсостояния – состояния, являющиеся частью других состояний. Простым называется такое состояние, которое не имеет внутренней структуры. Состояние, у которого есть подсостояния, называется составным. Составное состояние изображается так же, как и простое, но имеет дополнительный графический раздел, в котором показаны подсостояния. Глубина вложенности состояний не ограничена. Если в объемлющем составном состоянии имеется несколько подсостояний, то говорят, что объект одновременно находится в составном состоянии и в одном из подсостояний.
Пример. На рис. 6.27 показаны внутренние детали составного состояния "Охлаждение", то есть вложенные в него состояния.
Рис. 6.27. Вложенные состояния
Переходам между состояниями разрешено начинаться и кончаться на любом уровне. Рассмотрим различные формы переходов:
– переход между одноуровневыми состояниями (такой, как из "Готовность" в "Выполнение") – простейшая форма перехода;
– переход непосредственно в подсостояние (как переход из "Ожидание" в "Начальное"), или непосредственно из подсостояния (как из "Выполнение" в "Ожидание"), или одновременно и то, и другое;
– переход из составного состояния (как из состояния "Охлаждение" через событие "Сбой" в состояние "Повреждение");
– переход в состояние с вложенными подсостояниями (например, предыдущий переход в состояние "Повреждение").
Если целевое состояние является составным, то оно должно иметь некоторое начальное подсостояние, куда управление попадает при входе в составное состояние после выполнения ассоциированного с ним действия при входе (если таковое определено). Если же целевым является одно из вложенных состояний, то управление попадает в него, но опять-таки после выполнения действий при входе в объемлющее составное состояние и в подсостояние (если таковые определены).
Указание перехода из составного состояния означает, что он осуществляется из каждого подсостояния этого суперсостояния. Для перехода, исходящего из составного состояния, когда исходным является либо оно само, либо какое-либо из его подсостояний, управление сначала покидает вложенное подсостояние (тогда выполняется его действие при выходе, если оно определено), а затем – составное состояние (тогда также выполняется действие при выходе).
Диаграмма деятельности
Диаграмма деятельности показывает поток переходов от одной деятельности к другой. Она включает состояния деятельности, состояния действия и переходы.
Диаграмма деятельности, как и диаграмма состояний, отражает процесс перехода из состояния в состояние. При этом все или большинство состояний являются состояниями деятельности, а все или большинство переходов обусловлены завершением деятельности в состоянии-источнике.
Состояниясистемы, представляющие собой выполнение некоторого действия, называют состояниями действия. Состояния действия не могут быть подвергнуты декомпозиции, как и сами действия.
Состояние деятельности можно представлять себе как составное состояние, поток управления которого включает только другие состояния деятельности и действий. Состояния деятельности могут быть подвергнуты дальнейшей декомпозиции, вследствие чего выполняемую деятельность можно представить с помощью других диаграмм деятельности. Состояния деятельности не являются атомарными, то есть могут быть прерваны. Предполагается, что для их завершения требуется заметное время.
Можно считать, что состояние действия – это частный вид состояния деятельности, а конкретнее – такое состояние, которое не может быть подвергнуто дальнейшей декомпозиции.
Состояния деятельности и действия изображаются прямоугольниками с закругленными краями (рис. 6.28). Внутри такого значка можно записывать произвольное выражение. При этом у состояния деятельности могут быть дополнительные части, такие как действия входа и выхода (то есть выполняемые соответственно при входе в состояние и выходе из него) и подсостояния.
Рис. 6.28. Состояния и переходы Рис. 6.29. Ветвление
Когда действие или деятельность в некотором состоянии завершается, поток управления сразу переходит в следующее состояние действия или деятельности. Для описания этого потока используются переходы, показывающие путь из одного состояния действия или деятельности в другое. Переход изображается простой линией со стрелкой, как показано на рис. 6.28. Такие переходы являются нетриггерными (переходами по завершении), поскольку управление по завершении работы в исходном состоянии немедленно передается дальше.
После того как действие в данном исходном состоянии закончилось, выполняется определенное для него действие выхода (exit). Далее, безо всякой задержки, поток управления по переходу попадает в очередное состояние действия или деятельности. При этом выполняется определенное для нового состояния действие входа (entry), затем – действие или деятельность самого состояния и следующий переход. Поток управление должен где-то начинаться и заканчиваться. Как показано на рис. 6.28, можно задать как начальное состояние, так и конечное.
Если последовательных переходов недостаточно для моделирования потока управления, можно включить в модель ветвление, которое описывает различные пути выполнения в зависимости от значения некоторого булевского выражения. Как видно из рис. 6.29, точка ветвления представляется ромбом. В точку ветвления может входить ровно один переход, а выходить – два или более. Для каждого исходящего перехода задается булевское выражение, которое вычисляется только один раз при входе в точку ветвления. Ни для каких двух исходящих переходов эти сторожевые условия не должны одновременно принимать значение "истина", иначе поток управления окажется неоднозначным. Но эти условия должны покрывать все возможные варианты, иначе поток остановится. Для удобства разрешается использовать ключевое слово else для пометки того из исходящих переходов, который должен быть выбран в случае, если условия, заданные для всех остальных переходов, не выполнены.
Диаграммы деятельности могут служить в качестве блок-схем, причем внутри состояний можно записывать действия, применяя синтаксис используемого языка программирования. Например, на рис. 6.30 показана часть диаграммы деятельности, изображающая итерационный процесс.
Пример. На рис 6.31 изображена диаграмма деятельности, моделирующая структуру работ по возведению здания.
Рис. 6.30. Итерационный процесс
Рис. 6.31. Диаграмма деятельности для работ по возведению здания
ЛИТЕРАТУРА
1. Бадд Т. Объектно-ориентированное программирование в действии. – СПб.: "Питер", 1997.
2. Боггс У., Боггс М. UML и Rational rose. – М.: Лори, 2000.
3. Буч Г. Объектно-ориентированное проектирование с примерами применения. – М.: Конкорд, 1992.
4. Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на С++. – М.: "Издательство Бином", СПб.: "Невский диалект", 1998.
5. Буч Г., Рамбо Д., Джекобсон А. Язык UML. Руководство пользователя. – М.: ДМК, 2000.
6. Пол А. Объектно-ориентированное программирование на С++. – СПб.; М.: "Невский диалект" – "Издательство Бином", 1999.
7. Романовский К.Ю., Кузнецов С.В., Кознов Д.В. Объектно-ориентированный подход и диаграммы классов в UML // Объектно-ориентированное визуальное моделирование. – CПб: Изд-во С.-Петербургского ун-та, 1999.
8. Страуструп Б. Язык программирования С++. – СПб.; М.: "Невский диалект" – "Издательство Бином", 1999.
9. Фаулер М., Скотт К. UML в кратком изложении. Применение стандартного языка объектного моделирования. – М.: Мир, 1999.
10. Фридман А.Л. Основы объектно-ориентированной разработки программных систем. – М.: Финансы и статистика, 2000.
ОГЛАВЛЕНИЕ
Стр.
ВВЕДЕНИЕ .................................................................................................... 3
1. СЛОЖНОСТЬ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ........................... 4
2. ОБЪЕКТНАЯ МОДЕЛЬ ........................................................................... 8
2.1. Абстрагирование ........................................................................... 8
2.2. Инкапсуляция ............................................................................... 13
2.3. Модульность ................................................................................ 15
2.4. Иерархичность ............................................................................. 18
2.5. Типизация ..................................................................................... 21
2.6. Параллелизм ................................................................................ 23
2.7. Сохраняемость ............................................................................. 23
3. ОБЪЕКТЫ ............................................................................................... 24
3.1. Состояние ..................................................................................... 24
3.2. Поведение ..................................................................................... 25
3.3. Идентичность ............................................................................... 28
3.4. Отношения между объектами ..................................................... 32
4. КЛАССЫ .................................................................................................. 34
4.1. Ассоциация ................................................................................... 34
4.2. Агрегация ..................................................................................... 35
4.3. Обобщение ................................................................................... 36
4.3.1. Наследственная иерархия ................................................ 36
4.3.2. Наследование и типизация .............................................. 40
4.3.3. Множественное наследование ......................................... 43
4.4. Зависимость .................................................................................. 45
4.5. Инстанцирование ......................................................................... 46
4.6. Переменные и операции класса ................................................... 48
4.7. Интерфейсы .................................................................................. 49
4.8. Группирование классов ............................................................... 50
5. ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ АНАЛИЗ................................. 52
6. ОСНОВНЫЕ КОНСТРУКЦИИ ЯЗЫКА UML .................................... 55
6.1. Диаграмма классов ...................................................................... 56
6.2. Диаграмма объектов .................................................................... 60
6.3. Диаграммы взаимодействий ....................................................... 61
6.2. Диаграмма состояний .................................................................. 64
6.5. Диаграмма деятельности ............................................................. 69
ЛИТЕРАТУРА ............................................................................................. 71
Дополнение