Я понимаю, что State pattern
можно использовать для моделирования объектов, которые изменяют поведение в зависимости от состояния и различных состояний, которые может иметь Context
, инкапсулируется в конкретные классы, представляющие интерфейс State
. Я не совсем понимаю, как происходит переход состояния в этот шаблон. Может ли индивид states
знать и решать, кто следует за ними, или это Context
, который решает, какое состояние он получит дальше?
Кто определяет государственные переходы в государственной схеме?
Ответ 1
Из книги шаблонов проектирования GOF (это есть в разделе "Реализация" ):
1. Кто определяет переходы состояния? В шаблоне State не указывается, какой участник определяет критерии для перехода состояния. Если критерии фиксированы, то они могут быть полностью реализованы в контексте. Однако, как правило, более гибко и целесообразно позволить самим государственным подклассам указывать свое правопреемство и когда переходный период. Для этого требуется добавить интерфейс в контекст, который позволяет объектам State напрямую указывать текущее состояние контекста.
Децентрализация логики перехода таким образом упрощает изменение или расширение логики путем определения новых подклассов состояния. Недостатком децентрализации является то, что один подкласс государства будет иметь знания по меньшей мере о другом, который вводит зависимости реализации между подклассами.
Ответ 2
Может быть, относительно конкретный пример может прояснить. Надеюсь, я правильно понимаю его.
Предположим, что стиральная машина имеет два состояния (ON, Off). После словаря GoF:
- Контекст = > Стиральная машина
- Состояние = > СтиральнаямашинаState
- Конкретные состояния = > StateOn, StateOff
Для перехода состояния через государственные подклассы (в нашем случае StateOn и StateOff) нам нужно иметь способ изменения состояния Context:
class WashingMachine {
WashingMachineState state;
...
protected void setState(WashingMachineState newState) {
state = newState;
}
someMethod () {
...
state.pushStartButton(this);
...
}
}
abstract class WashingMachineState {
protected void run();
protected void pushStartButton(WashingMachine wm);
}
class StateOn extends WashingMachineState {
...
void pushStartButton(WashingMachine wm) {
wm.setState(new StateOff())
}
}
class StateOff extends WashingMachineState {
...
void pushStartButton(WashingMachine wm) {
wm.setState(new StateOn())
}
}
Просто имейте в виду, что есть несколько способов его реализации, креативность помогает!