Паттерн «Состояние»
В паттерне «Состояние» поведение класса изменяется в зависимости от его состояния. Этот тип паттерна проектирования относится к поведенческим паттернам.
В паттерне «Состояние» мы создаём объекты, представляющие различные состояния, и объект-контекст, поведение которого изменяется по мере изменения объекта состояния.
Паттерн «Состояние» позволяет объекту изменять своё поведение при изменении его внутреннего состояния, так что объект демонстрирует разное поведение в разных состояниях. Инкапсулируя каждое состояние в отдельный класс, он позволяет избежать использования большого количества условных операторов для реализации переключения состояний.
Введение
назначение
Он позволяет объекту изменять своё поведение при изменении его внутреннего состояния, создавая впечатление, будто объект изменил свой класс.
Основные решаемые проблемы
- Паттерн «Состояние» решает проблему зависимости поведения объекта от его состояния, позволяя объекту переключать поведение при изменении состояния.
Сценарий использования
- Используйте его, когда в коде много условных операторов и эти условные операторы зависят от состояния объекта.
Подход к реализации
- Определите интерфейс состояния: объявляет один или несколько методов для инкапсуляции поведения конкретного состояния.
- Создайте конкретные классы состояний: реализует интерфейс состояния и реализует конкретное поведение в зависимости от разных состояний.
- Определите класс контекста: содержит ссылку на объект состояния и обновляет своё поведение при изменении состояния.
Ключевой код
- Интерфейс состояния: объявляет методы поведения.
- Конкретный класс состояния: реализует интерфейс состояния и инкапсулирует конкретное поведение.
- Класс контекста: хранит объект состояния и предоставляет методы для изменения его состояния.
Пример приложения
- Состояние баскетболиста: У спортсмена могут быть такие состояния, как нормальное, аномальное и исключительное.
- Колокольный набор маркиза И из Цзэн: Колокольный набор служит контекстом, а разные колокола (состояния) создают разные исполнительские эффекты.
Преимущества
- Инкапсулирует правила переходов состояний: Инкапсулирует логику переходов состояний внутри объектов состояний.
- Легко расширять: Добавление новых классов состояний не влияет на существующий код.
- Централизует поведение, связанное с состоянием: Сосредоточивает всё поведение, относящееся к конкретному состоянию, в одном классе.
- Упрощает условные операторы: Позволяет избежать использования большого количества условных операторов для переключения поведения.
- Совместное использование состояний: Позволяет нескольким объектам контекста совместно использовать один и тот же объект состояния.
Недостатки
- Увеличивает количество классов и объектов: Каждое состояние требует конкретного класса состояния.
- Сложная реализация: Структура и реализация паттерна относительно сложны.
- Недостаточная поддержка принципа открытости-закрытости: Добавление новых состояний или изменение поведения состояний может потребовать изменений в существующем коде.
Рекомендации по использованию
- Когда поведение объекта изменяется вместе с его состоянием, рассмотрите использование паттерна «Состояние».
- Паттерн «Состояние» подходит для замены сложных условных операторов или ветвлений.
Примечания
- Паттерн «Состояние» подходит, когда количество состояний ограничено (обычно не более 5).
- Используйте с осторожностью, чтобы не сделать систему чрезмерно сложной.
Структура
Паттерн «Состояние» включает следующие основные роли:
Context: Определяет интерфейс, который интересен клиентам, и хранит ссылку на текущий объект состояния. Контекст может делегировать обработку поведения, связанного с состоянием, объекту состояния.
State: Определяет интерфейс для инкапсуляции поведения состояния, связанного с контекстом.
Конкретное состояние: Реализует интерфейс состояния и отвечает за обработку поведения, связанного с этим состоянием. Объект конкретного состояния обычно хранит внутри ссылку на объект контекста, чтобы иметь возможность переключаться в разные состояния в зависимости от различных условий.
Реализация
Мы создадимState-интерфейс и реализациюStateКласс сущности состояния этого интерфейса.ContextКласс с определённым состоянием.
StatePatternDemo, наш демонстрационный класс используетContextи объекты состояний, чтобы продемонстрировать, как поведение Context меняется при изменении его состояния.
Шаг 1
Создайте интерфейс.
State.java
Шаг 2
Создайте классы сущностей, реализующие интерфейс.
StartState.java
StopState.java
Шаг 3
СоздайтеContextкласс.
Context.java
Шаг 4
ИспользованиеContextЧтобы увидеть, когда состояниеStateПоведение изменяется при изменении состояния.
StatePatternDemo.java
Шаг 5
Запустите программу, выведите результат:
Player is in start state Start State Player is in stop state Stop State