Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Uml Book (Rus).doc
Скачиваний:
15
Добавлен:
11.08.2019
Размер:
58.74 Mб
Скачать

Подсостояния

Рассмотренные выше свойства состояний и переходов решают целый ряд ти­пичных проблем моделирования автоматов. Но у автоматов, рассматриваемых в UML, есть свойство, которое позволяет еще больше упростить моделирование сложного поведения. Это подсостояние (Substate) - состояние, являющееся час­тью другого состояния. Например, Обогреватель может находиться в состоянии Обогрев, внутри которого содержится еще одно состояние - Активация. В та­ком случае говорят, что объект находится одновременно в состояниях Обогрев и Активация.

Простым называется такое состояние, которое не имеет внутренней структуры. Состояние, у которого есть подсостояния, то есть вложенные состояния, именует­ся составным. Оно может содержать как параллельные (независимые), так и по­следовательные (непересекающиеся) подсостояния. В UML составное состояние изображается так же, как и простое, но имеет дополнительный графический раз­дел, в котором показан вложенный автомат. Глубина вложенности состояний не ограничена. (Вложенная структура составного состояния подобна композиции -см. главы 5 и 10.)

Последовательные подсостояния. Рассмотрим задачу моделирования банкомата. Система может находиться в одном из трех основных состояний: Ожидание (дей­ствий со стороны пользователя), Активен (выполняет транзакцию, запрошенную пользователем) или Обслуживается (возможно, пополняется запас банкнот). В состоянии Активен поведение банкомата описывается простой схемой: прове­рить счет пользователя, выбрать тип транзакции, выполнить транзакцию, напечатать квитанцию. После печати банкомат возвращается в состояние Ожидание. Эти этапы можно представить как состояния Проверка, Выбор, Обработка, Печать. Стоило бы даже дать пользователю возможность выбрать и выполнить несколько транзакций после того, как проверка счета выполнена, но еще до печати окончательной квитанции.

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

Использование последовательных подсостояний позволяет упростить моделиро­вание этой задачи, как показано на рис. 21.5. Здесь у состояния Активен имеется внутренний автомат, в который входят подсостояния Проверка, Выбор, Обработ­ка, Печать. Состояние банкомата изменяется с Ожидание на Активен, когда пользо­ватель вставляет в прорезь кредитную карту. При входе в состояние Активен вы­полняется действие readCard (прочитатьКарту). Начав с исходного состояния внутреннего автомата, управление переходит в состояние Проверка, затем - в Вы­бор, и, наконец, в состояние Обработка. После выхода из состояния Обработка управление может вернуться в Выбор (если пользователь избрал другую транзак­цию) или попасть в Печать. Из состояния Печать предусмотрен нетриггерный пе­реход назад в Ожидание. Обратите внимание, что у состояния Активен есть действие при выходе, которое обеспечивает выбрасывание кредитной карты (ejectCard).

Обратите внимание также на переход из состояния Активен в состояние Ожи­дание, инициируемый событием cancel. В любом подсостояний состояния Ак­тивен пользователь может отменить транзакцию, что вернет банкомат в состоя­ние Ожидание (но лишь после возврата кредитной карты владельцу, то есть после

выполнения действия при выходе из состояния Активен, что произойдет вне за­висимости от того, чем вызван переход из этого состояния). Если бы подсостоя­ний не было, то пришлось бы вводить переход, инициируемый событием cancel из каждого состояния вложенного автомата.

Такие подсостояния, как Проверка и Обработка, называются последователь­ными или непересекающимися. Если в объемлющем составном состоянии имеет­ся несколько непересекающихся подсостояний, то говорят, что объект одновре­менно находится в составном состоянии и ровно в одном из подсостояний. Таким образом, последовательные подсостояния разбивают множество вариантов состав­ного состояния на непересекающиеся (дизъюнктные) части.

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

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

Примечание Вложенный последовательный автомат может иметь не более од­ного начального и не более одного конечного состояния.

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

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

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

В UML для моделирования такой идиомы применяется более простой меха­низм - исторические состояния (History states). Историческое состояние позво­ляет составному состоянию, содержащему последовательные подсостояния, запо­минать, какое из подсостояний было текущим в момент выхода из составного состояния. На рис. 21.6 недавнее (shallow) историческое состояние представлено в виде небольшого кружочка с символом Н.

Переход, необходимый для активации последнего подсостояния, показывают как ведущий извне составного состояния прямо в историческое состояние. При пер­вом входе в составное состояние истории еще нет. В этом заключается смысл оди­ночного перехода из исторического состояния в одно из последовательных подсо­стояний, например в Сбор. Целевое для этого перехода состояние - это не что иное, как начальное состояние вложенного автомата при первом входе в него. Предполо­жим далее, что событие запрос поступило, когда агент находился в состоянии РезервноеКопирование и подсостояний Копирование. При этом управление покидает оба этих состояния (возможно, после выполнения действий при выхо­де) и возвращается в состояние Команда. Когда завершается действие в состоянии Команда, нетриггерный переход возвращает агента в историческое состояние составного состояния РезервноеКопирование. На этот раз, поскольку у вложен­ного автомата уже есть история, управление попадает в состояние Копирование -обходя состояние Сбор, так как Копирование было последним активным подсостоянием перед выходом из состояния РезервноеКопирование.

Примечание Символом Н обозначается недавняя история, в которой запоминает­ся предшествующее состояние только самого внешнего из вложенных автоматов. Можно определить и давнюю (deep) историю, которая изображается кружочком с символом Н*. Давняя история способна запомнить последние состояния всех вложенных подавтоматов лю­бого уровня вложенности. При наличии только одного уровня вложен­ности давняя и недавняя истории семантически эквивалентны. Если же глубина вложенности больше 1, то недавняя история помнит только самое внешнее из вложенных подсостояний, а давняя - все вложенные подсостояния любого уровня.

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

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

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

На рис. 21.7 показано развернутое представление состояния. Обслуживается (см. рис. 21.5). Это состояние разделено на два параллельных подсостояния: Тестирование и приемКоманд, которые изображены как вложенные в состояние Об­служивается, но отделены друг от друга пунктирной линией. Каждое из этих двух параллельных подсостояний далее разделено на последовательные подсостояния (о разделении и слиянии см. главу 19). Когда управление переходит из Стояния Ожидание в состояние Обслуживается, происходит разделение на два Параллельных потока: объемлющий объект находится в состояниях Тестирование и приемКоманд. Кроме того, находясь в состоянии приемКоманд, этот объект будет либо в состоянии Жду, либо в состоянии Команда.

Примечание Именно это отличает последовательные состояния от параллель­ных. Если имеется два или более последовательных подсостояний одного и того же уровня вложенности, то объект может находить­ся только в одном из них. Если налицо два или более параллельных подсостояний одного и того же уровня вложенности, то объект будет одновременно находиться в одном из последовательных со­стояний каждого из них.

Выполнение двух параллельных подсостояний протекает одновременно. В кон­це концов каждый из вложенных параллельных подавтоматов достигнет своего конечного состояния. Если один из них «придет к финишу» раньше другого, то поток управления будет ждать. Когда и второй автомат доберется до своего ко­нечного состояния, оба потока вновь сольются в один.

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]