Здравствуйте! |
Моделирование параллельного поведения с помощью диаграмм состояний
Сложные переходы и псевдосостояния
Рассмотренное выше понятие перехода вполне достаточно для большинства типичных расчетно-аналитических задач. Однако современные программные системы могут реализовывать сложную логику поведения отдельных своих компонентов. Иногда для адекватного представления процесса изменения состояний семантика обычного перехода для них недостаточна. С этой целью в языке UML специфицированы дополнительные обозначения и свойства, которыми могут обладать отдельные переходы на диаграмме состояний.
В отдельных случаях возникает необходимость явно показать ситуацию, когда переход может иметь несколько исходных состояний или целевых состояний. Такой переход получил название - параллельный переход. Введение в рассмотрение параллельных переходов может быть обусловлено необходимостью синхронизировать и/или разделить отдельные процессы управления на параллельные нити без спецификации дополнительной синхронизации в параллельных конечных подавтоматах.
Графически такой переход изображается вертикальной черточкой, аналогично обозначению перехода в известном формализме сетей Петри. Если параллельный переход имеет две или более исходящих из него дуг (рис. 10.6, а), то его называют разделением (fork). Если же он имеет две или более входящие дуги (рис. 10.6, б), то его называют слиянием (join). Текстовая строка спецификации параллельного перехода записывается рядом с черточкой и относится ко всем входящим или исходящим дугам.
Рис. 10.6. Графическое изображение перехода-разделения в параллельные подсостояния (а) и перехода-слияния из параллельных подсостояний (б)
Срабатывание параллельного перехода происходит следующим образом. В первом случае происходит разделение составного конечного автомата на два конечных подавтомата, образующих параллельные ветви вложенных подпроцессов. При этом после срабатывания перехода-разделения моделируемая система или объект одновременно будет находиться во всех целевых подсостояниях этого параллельного перехода ( подсостояния 1 и 2). Далее процесс изменения состояний будет протекать согласно ранее рассмотренным правилам для составных состояний.
Во втором случае переход-слияние срабатывает, если имеет место событие-триггер для всех исходных состояний этого перехода, и выполнено (при его наличии) сторожевое условие. При срабатывании перехода-слияния одновременно покидаются все исходные подсостояния перехода ( подсостояния 3 и 4) и происходит переход в целевое состояние. При этом каждое из исходных подсостояний перехода должно принадлежать отдельному конечному подавтомату, входящему в составной конечный автомат (процессу Б).
Переход, стрелка которого соединена с границей составного состояния, обозначает переход в это составное состояние (переход a на рис. 10.7). Он эквивалентен переходу в начальное состояние каждого из конечных подавтоматов (единственному на рис. 10.7), входящих в состав данного состояния-композита. Переход f, выходящий из составного состояния (рис. 10.7), относится к каждому из вложенных состояний. Это означает, что моделируемая система или объект при наступления события f может покинуть данное составное состояние, находясь в любом из его вложенных состояний В и Г.
Иногда желательно реализовать ситуацию, когда выход из отдельного вложенного состояния соответствовал бы также выходу из составного состояния. В этом случае изображают переход, который непосредственно выходит из вложенного состояния и пересекает границу состояния-композита (переход c на рис. 10.7). Аналогично, допускается изображение переходов, входящих извне состояния-композита в отдельное вложенное состояние (переход b на рис. 10.7).
Переход d является внутренним для рассматриваемого состояния-композита и никак не влияет на выход из состояния-композита. Выход из данного составного состояния также возможен при наступлении события e, которое приводит в его конечное состояние, а из него - в состояние Е, находящееся вне данного состояния-композита.
В общем случае поведение параллельных конечных подавтоматов происходит независимо друг от друга, что позволяет, например, моделировать многозадачность в программных системах. Однако в отдельных ситуациях может возникнуть необходимость учесть в модели синхронизацию наступления отдельных событий и срабатывание соответствующих переходов. Для этой цели в языке UML имеется псевдосостояние, которое называется синхронизирующим состоянием или состоянием синхронизации.
Состояние синхронизации (synch state) - псевдосостояние в конечном автомате, которое используется для синхронизации параллельных областей конечного автомата.
Синхронизирующее состояние обозначается небольшой окружностью, внутри которой помещен символ звездочки "*". Оно используется совместно с переходом-слиянием или переходом-разделением для того, чтобы явно указать события в других конечных подавтоматах, оказывающие непосредственное влияние на поведение данного подавтомата.
Так, например, при включении компьютера с некоторой сетевой операционной системой параллельно начинается выполнение нескольких процессов. В частности, происходит проверка пароля пользователя и запуск различных служб. При этом работа пользователя на компьютере станет возможной только в случае успешной его аутентификации, в противном случае компьютер может быть выключен. Рассмотренные особенности синхронизации этих параллельных процессов учтены на соответствующей диаграмме состояний с помощью синхронизирующего состояния (рис. 10.8).
Рекомендации по построению диаграмм состояний
По своему назначению диаграмма состояний не является обязательным представлением в модели и как бы "присоединяется" к тому элементу, который, по замыслу разработчиков, имеет нетривиальное поведение в течение своего жизненного цикла. Наличие у системы нескольких состояний, отличающихся от простой дихотомии "исправен - неисправен", "активен - неактивен", "ожидание - реакция на внешние действия", уже служит признаком необходимости построения диаграммы состояний. В качестве начального варианта диаграммы состояний, если нет очевидных соображений по поводу состояний объекта, можно воспользоваться подобными состояниями, в качестве составных, уточняя их (детализируя их внутреннюю структуру) по мере рассмотрения логики поведения моделируемой системы или объекта.
При выделении состояний и переходов следует помнить, что длительность срабатывания отдельных переходов должна быть существенно меньшей, чем нахождение моделируемых элементов в соответствующих состояниях. Каждое из состояний должно характеризоваться определенной устойчивостью во времени. Другими словами, из каждого состояния на диаграмме не может быть самопроизвольного перехода в какое бы то ни было другое состояние. Все переходы должны быть явно специфицированы, в противном случае построенная диаграмма состояний является либо неполной (неадекватной), либо ошибочной с точки зрения нотации языка UML (ill formed).
При разработке диаграммы состояний нужно постоянно следить, чтобы объект в каждый момент мог находиться только в единственном состоянии. Если это не так, то данное обстоятельство может быть как следствием ошибки, так и неявным признаком наличия параллельности поведения у моделируемого объекта. В последнем случае следует явно специфицировать необходимое число конечных подавтоматов, вложив их в то составное состояние, которое характеризуется нарушением условия одновременности.
Следует произвести обязательную проверку, чтобы никакие два перехода из одного состояния не могли сработать одновременно. Другими словами, необходимо выполнить требование отсутствия конфликтов у всех переходов, выходящих из одного и того же состояния. Наличие такого конфликта может служить признаком ошибки, либо параллельности или ветвления рассматриваемого процесса. Если параллельность по замыслу разработчика отсутствует, то следует ввести дополнительные сторожевые условия либо изменить существующие, чтобы исключить конфликт переходов. При наличии параллельности следует заменить конфликтующие переходы одним параллельным переходом типа ветвления.
Использование исторических состояний оправдано в том случае, когда необходимо организовать обработку исключительных ситуаций (прерываний) без потери данных или выполненной работы. При этом применять исторические состояния, особенно глубокие, необходимо с известной долей осторожности. Нужно помнить, что каждый из конечных подавтоматов может иметь только одно историческое состояние. В противном случае возможны ошибки, особенно, когда подавтоматы изображаются на отдельных диаграммах состояний.