Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсач / Методические указания.docx
Скачиваний:
0
Добавлен:
07.08.2024
Размер:
3.53 Mб
Скачать

7 Моделирование поведения

В этом разделе рассматриваются способы ответа на вопрос, как работает система?

Ответ на этот вопрос называется в UML моделью поведения. Поведение реальной программной системы целиком и полностью определяется кодом ее программы— как программа составлена, так она и выполняется (с точностью до сбоев) — «от себя» компьютер ничего не придумывает. Таким образом, модель поведения — это описание алгоритма работы системы.

7.1 Диаграмма автомата

После создания одной или нескольких диаграмм вариантов использования системный аналитик с заказчиком определяют приоритетность проработки вариантов использования и детализируют их. Главная цель данной процедуры – поиск ответа на вопрос: «В процессе какого поведения система обеспечивает необходимую функциональность?».

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

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

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

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

  • сигналы

  • вызовы

  • истечение промежутка времени

  • изменение состояния

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

Вызов (call, англ.) – спецификация факта посылки синхронного сообщения между объектами, предписывающего выполнение операции (действия или деятельности) объектом, которому посылается сообщение. Синхронность означает, что после посылки вызова объект-отправитель передает управление объекту-получателю и, после выполнения последним операции, получает управление обратно. Например, закрасить фигуру красным фоном fill(red) или рассчитать допускаемые скорости calculateVdop().

Событие времени – спецификация факта, обозначающее истечение промежутка времени с момента входа в текущее состояние. В UML данный факт специфицируется с помощью ключевого слова «after» (после, англ.). Например, after(2 seconds).

Событие изменения состояния – спецификация логического (булевского) условия. В контексте диаграмм состояний, данное событие приводит к изменению состояния экземпляра сущности. В UML оно специфицируется с помощью ключевого слова «when» (когда, англ.) или сторожевого условия. Например, when(A < B) или [A < B].

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

С остояние отображается в виде прямоугольника со скругленными углами, внутри которого записывается имя. Рекомендуется в качестве имени использовать глаголы в настоящем времени (звенит, печатает, ожидает) или причастия (занят, свободен, передано, получено).

Рисунок 65 - Способы отображения состояний

Характеристика состояния может содержать описание выполняемых операций, перед которыми указывается одна из стандартных меток:

  • entry (вход, англ.) – действие при входе, выполняемое вне зависимости от того, по какому переходу был выполнен вход в состояние. Например, создать соединение с базой данных entry / createConnect();

  • exit (вход, англ.) – действие при выходе, выполняемое вне зависимости от того, по какому переходу был выполнен выход из состояния. Например, закрыть соединение с базой данных exit / closeConnect();

  • do (выполнять, англ.) – деятельность в состоянии. Находясь в состоянии, объект может бездействовать и ждать наступления некоторого события, а может выполнять длительную операцию. Например, рассчитать допускаемые скорости do / calculateVdop(). Допускается указывать несколько операций в виде отдельных строк, каждая из которых начинается с метки do, или в виде одной строки, операции в которой отделены друг от друга точкой с запятой;

  • newTarget (новое задание, англ.) – внутренний переход, предписывающий обработку новых событий, не покидая текущего состояния. При выполнении внутреннего перехода повторно не выполняются действия при входе или выходе из состояния. Например, временная остановка (прерывание) расчета допускаемых скоростей, newTarget / pauseCalculateVdop();

  • defer (отложить, англ.) – отложенное событие, обработка которого предписывается в другом состоянии, но после того, как все операции в текущем будут завершены. Например, отображение на экране ошибок в исходных данных defer / showDataError().

Н а рисунке 66 показан пример состояния с характеристикой.

Рисунок 66 - Пример состояния

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

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

а) начальное состояние б) конечное состояние

Рисунок 67 - Начальное и конечное состояния

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

Различают два вида переходов: нетриггерный и триггерный. Переход первого вида, называемый также переходом по завершении, срабатывает неявно, когда все основные операции (с метками entry, do и exit) в исходном состоянии успешно завершают свою работу. Данный вид перехода обозначается стрелкой без надписи. Для наступления триггерного перехода необходимо наступление некоторого события, которое записывается над стрелкой. В общем случае, над стрелкой может быть записана строка текста вида «событие / действие». Указываемое действие представляет собой атомарную операцию, выполняемую сразу после срабатывания соответствующего перехода и до начала каких бы то ни было операций в целевом состоянии. Разрешается указывать не одно, а несколько отдельных действий, отделенных друг от друга точкой с запятой. Обязательное требование – все действия в списке должны четко различаться между собой и следовать в порядке их записи. Примеры спецификации переходов:

  • mouseClick() – нажатие кнопки мыши в момент, когда указатель находится над моделируемым объектом (например, над командной кнопкой, запускающей процедуру определения допускаемых скоростей);

  • mouseClick() / setFocus() – нажатие кнопки мыши с одновременным установление фокуса на моделируемом объекте;

  • mouseClick() [isEnabled() = true] / setFocus() – нажатие кнопки мыши с одновременным установление фокуса на моделируемом объекте при условии, что он доступен. В данном примере, объект переходит в новое состояние только в том случае, если произойдет событие и сторожевое условие будет истинно. Вычисление истинности сторожевого условия происходит только после возникновения ассоциированного с ним события, инициирующего соответствующий переход. Если событие не произошло или сторожевое условие ложно, то переход не срабатывает и действие, записанное через «/» не выполняется;

  • when(14:00) или [getTime() = 14:00] – текущее время на компьютере равно 14 часам;

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

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

На рисунке 68 показаны простой и рефлексивный переходы.

Рисунок 68 - Простой (а) и рефлексивный (б) переходы

На диаграмме могут отображаться составные состояния (composite state, англ.), состоящие из вложенных в него подсостояний (substate, англ.).

Подсостояния отображаются внутри составного состояния (подавтомата).

Рисунок 69 - Составное состояние и подсостояния

Составное состояние может содержать параллельные подавтоматы или последовательно выполняемые подсостояния. При этом любое из подсостояний, в свою очередь, может являться составным состоянием.

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

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

Рисунок 70 - Составное состояние с вложенными параллельными подавтоматами

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

Рисунок 71 - Пример составного состояния со скрытой внутренней структурой

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

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

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

Рисунок 72 - Параллельные переходы

На рисунке 72 переход из состояния 1 выполняется параллельно в подсостояния 1 и 4, в то время как переход из состояния 2 – в подсостояния 1 и 3. Переходы в или из подсостояний могут обладать еще более сложной семантикой. Так на рисунке 23 отображены следующие варианты переходов:

  • переход в конкретное подсостояние (переход из состояния «Выбор участка» строго в начальное подсостояние);

  • выход из конкретного подсостояния (переходы из подсостояний «Формирование задания» и «Расчет» в состояние «Корректировка исходных данных»);

  • H

    переход, стрелка которого соединена с границей некоторого составного состояния, обозначает переход в начальное подсостояние податомата (переход из состояния «Корректировка исходных данных»). Если внутри составного состояния имеется знак истории состояния (state history, англ.), то переход выполняется в подсостояние, из которого в последний раз был выполнен выход из составного состояния, несмотря на начальное состояние. Так в примере, если после корректировки данных впервые выполняется определение скоростей, то по переходу система попадает в начальное подсостояние. Если в подсостояниях «Формирование задания» и «Расчет» обнаруживается необходимость корректировки исходных данных, то возврат управления осуществляется в вызвавшее корректировку подсостояние;

  • переход, стрелка которого выходит из границы некоторого составного состояния, обозначает переход из его конечного подсостояния (переход в конечное состояние).

Рисунок 73 - Сложные переходы

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

Синхронизирующее состояние обозначается небольшой окружностью, внутри которой помещен символ звездочки «*». Оно используется совместно с переходом-соединением или переходом-ветвлением для того, чтобы явно указать события в других подавтоматах, оказывающие непосредственное влияние на поведение данного подавтомата. На рисунке 74 показан пример использования синхронизирующих состояний.

Рисунок 74 - Диаграмма состояний с синхронизирующими состояниями

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

Еще один пример. Как известно, диаграммы состояний строятся для моделирования поведения объекта. То есть, на этих диаграммах отображается жизненный цикл одного объекта, начиная с момента его создания и заканчивая его уничтожением. Диаграммы состояний не требуется создавать для каждого класса. Многие проекты вообще обходятся без них. Явным сигналом, говорящем о необходимости моделирования поведения объекта, является наличие в классе атрибута, от значений которых зависит это самое поведение.

На рисунке 75 изображена диаграмма, демонстрирующая поведение объекта класса Договор. В данном случае хорошим индикатором нескольких состояний объекта являются атрибуты Статус в классе Договор. Наличие у экземпляра сущности нескольких состояний, отличающихся от простой схемы «исправен — неисправен» или «активен — неактивен», обосновывает необходимость построения диаграммы состояний. При выделении состояний и переходов следует помнить, что длительность срабатывания переходов должна быть существенно меньшей, чем нахождение моделируемого объекта в соответствующих состояниях. Каждое из состояний должно характеризоваться определенной устойчивостью во времени.

Рисунок 75 - Диаграмма состояний для объекта класса "Договор"

Как видно из диаграммы, начальным состоянием для этого объекта является состояние «Активен». Из этого состояния возможны три перехода.

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

Переход «Активен» – «Исполнен» выполняется в том случае, если одна из сторон по каким-либо причинам не выполняет условия договора, причем при наступлении данного события переход происходит в любом случае (это показано отсутствием ограждающего условия). Само состояние «Расторгнут» имеет входное действие (entry) «освободить рекламные площади», т. е. поведение, которое проявляется, когда объект переходит в данное состояние. То есть при расторжении договора освобождаются рекламные площади, которые по этому договору были арендованы.

Переход «Активен» – «Исполнен» обозначен событием «условия договора выполнены» с ограждающим условием «договор действует». Этим показано, что договор считается исполненным в том случае, когда выполнены все его условия, при этом договор продолжает действовать, т. е. площади, арендованные по данному договору, остаются заняты до окончания срока действия договора. Как только срок действия договора при выполненных его условиях истекает, договор переходит в состояние «Завершен». Это показано соответствующим переходом с событием «срок действия договора подошел к концу» с ограждающим условием «условия договора выполнены».

Как видно из диаграммы, конечными состояниями для объекта класса Договор, т. е. состояниями, в которых он может находиться непосредственно перед уничтожением, могут быть состояния «Расторгнут» или «Завершен». Конечные состояния (точки выхода) необязательны, т. е., к примеру, их могло не быть, если бы завершенные ли расторгнутые договоры не удалялись из системы. В данном случае предполагается, что после того, как договор расторгается или завершается, он удаляется из системы. Поэтому на диаграмме изображен переход из этих состояний в точку выхода (можно было изобразить две отдельные точки выхода для каждого из этих состояний).

Н аконец, последний пример - диаграмма состояний для системы управления банкоматом (рисунок 76), которая была уже описана диаграммой вариантов использования, т.е. взгляд на систему управления с другой точки зрения.

Рисунок 76 - Диаграмма состояний для системы управления банкоматом

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

Таким образом, диаграммы состояния документируют динамику поведения объекта, благодаря чему аналитики и разработчики получают о нем четкое представление.