Motivation
- If the state of the object changes, its behavior will change accordingly. For example, if the document is in a read-only state, the behavior supported by the document and the behavior supported by the read-write state may be completely different.
- How to transparently change the behavior of an object according to its state at runtime?
Pattern definition
Allows an object to change its behavior when its internal state changes. This makes the object appear to modify its behavior. -"Design Mode" GoF
Summary of main points
- State mode puts all behaviors related to a specific state into a sub-object of State. When the object state is switched, the corresponding object is switched; but at the same time, the interface of State is maintained, which realizes the relationship between specific operations and state transition. Decoupling.
- Conversion is atomic
- Similar to Strategy mode
Structure
Looking at this class diagram seems to be the same as the UML diagram of the strategy pattern?
https://www.cnblogs.com/wkfvawl/p/12453747.html
This is indeed the case. The two modes are structurally the same, but the intention is completely different. The strategy mode is a strategy algorithm that allows the user to specify the replacement, and the state mode is the automatic replacement of the state under certain conditions. The user cannot Specify the state, at most you can only set the initial state.
The explanation here is still a bit abstract. I found a vivid example in my mind. Although it is a bit dirty, the words are not rough, you can take a look.
https://www.zhihu.com/question/23693088
Basic code
#include <iostream> using namespace std; class Context; class State { // Abstract state class, define an interface to encapsulate the behavior related to a specific state of Context public : virtual void Handle (Context * c) = 0 ; virtual ~ State () {} }; class Context { // Maintain an instance of ConcreteState subclass, this instance is defined as the current state private : State * state; public : Context (State * s) {state = s;} void Request () { // //Process the request and set the next state state-> Handle ( this ); } void SetState (State * s) {state = s;} }; // Specific state class, each word class implements a state with Context Related behavior class ConcreteStateA: public State { public : void Handle (Context * c); }; class ConcreteStateB: public State { public : void Handle (Context * c); }; class ConcreteStateC: public State { public : void Handle (Context * c); }; void ConcreteStateA::Handle(Context* c) { cout << "ConcreteStateA" << endl; c->SetState(new ConcreteStateB()); } void ConcreteStateB::Handle(Context* c) { cout << "ConcreteStateB" << endl; c->SetState(new ConcreteStateC()); } void ConcreteStateC::Handle(Context* c) { cout << "ConcreteStateC" << endl; c->SetState(new ConcreteStateA()); } int main() { State* s = new ConcreteStateA(); Context* c = new Context(s); c->Request(); // ConcreteStateA 切换状态 c->Request(); // ConcreteStateB c->Request(); // ConcreteStateC delete s; delete c; return 0; }
Application scenario
The state mode reduces the dependence on each other by distributing various state transition logic between the subclasses of State. When the behavior of an object depends on its state, and it must change its behavior according to the state at runtime, you can consider using the state mode.
Advantages: localize the behaviors related to specific states, and separate the behaviors of different states.