Диаграмму состояний можно реализовать тремя основными способами: с помощью вложенного оператора switch, паттерна State и таблицы состояний. Самый прямой подход в работе с диаграммами состояний - это вложенный оператор switch, такой как на рис. 10.6
Хотя этот способ и прямой, но очень длинный даже для этого простого случая. Кроме того, при данном подходе очень легко потерять контроль, поэтому я не люблю применять его даже в элементарных ситуациях.
Паттерн «Состояние» (State pattern) [21] представляет иерархию классов состояний для обработки поведения состояний. Каждое состояние на диаграмме имеет свой подкласс состояния. Контроллер имеет методы для каждого события, которые просто перенаправляют к классу состояния. Диаграмма состояний, показанная на рис. 10.1, могла бы быть реализована с помощью классов, представленных на рис. 10.7.
Вершиной иерархии является абстрактный класс, который содержит описание всех методов, обрабатывающих события, но без реализации. Для каждого конкретного состояния достаточно переписать метод-обработчик определенного события, инициирующего переход из состояния.
|
|
Таблица состояний представляет диаграмму состояний в виде данных. Так, диаграмма на рис. 10.1 может быть представлена в виде табл. 10.1. Затем мы строим интерпретатор, который использует таблицу состояний во время выполнения программы, или генератор кода, который порождает классы на основе этой таблицы.
Очевидно, большая часть работы над таблицей состояний проводится однажды, но затем ее можно использовать всякий раз, когда надо решить проблему, связанную с состояниями. Таблица состояний времени выполнения может быть модифицирована без перекомпиляции, что в некотором смысле удобно. Шаблон состояний собрать легче, и хотя для каждого состояния требуется отдельный класс, но размер кода, который при этом надо написать, совсем невелик
Приведенные реализации практически минимальные, но они дают представление о том, как применять диаграммы состояний. В каждом случае реализация моделей состояний приводит к довольно стереотипной программе, поэтому обычно для этого лучше прибегнуть к тому или иному способу генерации кода.