Шаг 178.
Унифицированный язык моделирования UML.
Исторические состояния

    На этом шаге рассмотрим исторические состояния конечного автомата.

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

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

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

    В UML предусмотрен более простой способ моделирования подобных идиом – с помощью исторических состояний. Историческое состояние (history state) позволяет составному состоянию, включающему неортогональные подсостояния, "помнить" подсостояние, которое было активным на момент последнего перехода из составного состояния вовне. Как показано на рис. 1, историческое состояние изображается в виде маленького кружочка с буквой "H" (History).


Рис.1. Историческое состояние

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

    Цель этого перехода специфицирует начальное состояние вложенного автомата при первом входе. Предположим, что во время состояния BackingUp (РезервноеКопирование) и Copying (Копирование) посылается событие query (запрос). Управление покидает Copying и BackingUp (вызывая при необходимости их выходные действия) и возвращается к состоянию Command (Команда). Когда завершится деятельность Command, завершающий переход вернется к историческому состоянию составного состояния BackingUp. На этот раз, по скольку существует история вложенного автомата, управление передается состоянию Copying, минуя состояние Collecting, так как именно Copying было последним активным подсостоянием перед последним выходом из BackingUp.

    Буквой "H" обозначается поверхностная память, которая хранит лишь последнее состояние ближайшего вложенного автомата. Можно специфицировать и глубинную память, изобразив ее в виде маленького кружочка с символами "H*" внутри. Такая история хранит состояния всех вложенных автоматов. Если имеется только один уровень вложенности, то поверхностная и глубинная память семантически эквивалентны. Если же уровней вложенности несколько, поверхностная память хранит состояние только ближайшего вложенного автомата, а глубинная – всех автоматов, вложенных друг в друга на любую глубину.

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

    На следующем шаге рассмотрим ортогональные подсостояния на диаграмме состояний в UML.




Предыдущий шаг Содержание Следующий шаг