Диаграммы состояний (state machine diagrams) - это известная технология описания поведения системы. В том или ином виде диаграммы состояний существуют с 1960 года, и на заре объектно-ориентированного программирования они применялись для представления поведения системы. В объектно-ориентированных подходах вы рисуете диаграмму состояний единственного класса, чтобы показать поведение одного объекта в течение его жизни.
Всякий раз, когда пишут о конечных автоматах, в качестве примеров неизбежно приводят системы круиз-контроля или торговые автоматы. Поскольку они мне слегка наскучили, я решил использовать контроллер секретной панели управления в Готическом замке. В этом замке я хочу так спрятать свои сокровища, чтобы их было трудно найти. Для того чтобы получить доступ к замку сейфа, я должен вытащить из канделябра стратегическую свечу, но замок появится, только если дверь закрыта. После появления замка я могу вставить в него ключ и открыть сейф. Для дополнительной безопасности я сделал так, чтобы сейф можно было открыть только после извлечения свечи. Если вор не обратит внимания на эту предосторожность, то я спущу с цепи отвратительного монстра, который проглотит вора.
|
|
На рис. 10.1 показана диаграмма состояний класса контроллера, который управляет моей необычной системой безопасности. Диаграмма состояния начинается с состояния создаваемого объекта контроллера: состояния Wait (Ожидание). На диаграмме это обозначено с помощью начального псевдосостояния (initial pseudostate), которое не является состоянием, но имеет стрелку, указывающую на начальное состояние.
На диаграмме показано, что контроллер может находиться в одном из трех состояний: Wait (Ожидание), Lock (Замок) и Open (Открыт). На диаграмме также представлены правила, согласно которым контроллер переходит из одного состояния в другое. Эти правила представлены в виде переходов - линий, связывающих состояния.
Переход (transition) означает перемещение из одного состояния в другое. Каждый переход имеет свою метку, которая состоит из трех частей: триггер-идентификатор [защита]/активность (trigger-signature [guard]/acti-vity). Все они не обязательны. Как правило, триггер-идентификатор - это единственное событие, которое может вызвать изменение состояния. Защита, если она указана, представляет собой логическое условие, которое должно быть выполнено, чтобы переход имел место. Активность -это некоторое поведение системы во время перехода. Это может быть любое поведенческое выражение. Полная форма триггера-идентификатора может включать несколько событий и параметров. Переход из состояния Wait (рис. 10.1) в другое состояние можно прочесть как «В состоянии Wait, если свеча удалена, вы видите замок и переходите в состояние Lock».
|
|
Все три части описания перехода не обязательны. Пропуск активности означает, что в процессе перехода ничего не происходит. Пропуск защиты означает, что переход всегда осуществляется, если происходит инициирующее событие. Триггер-идентификатор отсутствует редко, но и так бывает. Это означает, что переход происходит немедленно, что можно наблюдать главным образом в состояниях активности, о чем я расскажу в нужный момент.
Когда в определенном состоянии происходит событие, то из этого состояния можно совершить только один переход, например в состоянии Lock (рис. 10.1) защиты должны быть взаимно исключающими. Если событие происходит, а разрешенных переходов нет - например закрытие сейфа в состоянии Wait или удаление свечи при открытой двери -событие игнорируется.
Конечное состояние (final state) означает, что конечный автомат закончил работу, что вызывает удаление объекта контроллера. Так что
для тех, кто имел неосторожность попасть в мою ловушку, сообщаю, что поскольку объект контроллера прекращает свое существование, я вынужден посадить кролика обратно в клетку, вымыть пол и перегрузить систему.
Помните, что конечные автоматы могут показывать только те объекты, которые непосредственно наблюдаются или действуют. Поэтому, хотя вы могли ожидать, что я положу что-нибудь в сейф или что-нибудь возьму оттуда, когда дверь открыта, я не отметил это на диаграмме, поскольку контроллер об этом ничего сообщить не может.
Когда разработчики говорят об объектах, они часто ссылаются на состояние объектов, имея в виду комбинацию всех данных, содержащихся в полях объектов. Однако состояние на диаграмме конечного автомата является более абстрактным понятием состояния; суть в том, что различные состояния предполагают различные способы реакции на события.