1.State模式适用场景
State模式在实际使用中比较多的适合状态的切换,因为我们经常会用到if...else if ...else...,进行状态切换,如果这种判断反复出现,则就可以考虑使用State设计模式来代替了。
2.State和Command两种设计模式的区别
State设计模式从调用者和被调用者出发,目的是封装调用者的行为,让调用者和统一的顶层接口交互;Command模式则从对象自身状态出发,不涉及调用者和被调用者,是对象自身状态变化导致的状态切换。
3.“开关状态切换”和“一般状态判断”
“开关状态切换”经常发生在GUI界面交互过程中,通过结合当前参数和状态,判断对象接下来应该切换到何种状态,被判断对象和更新对象都是同一个对象,如:
if (state.equals("1")) state = "welcome";
else if (state.equals("2")) state = "working";
else if (state.equals("3")) state = "welcome next time!";
和“一般状态判断”是不同的,后者根据其他对象的属性值来决定自身的状态,被判断对象和更新对象绝对不会是同一个对象。如:
if (which == 1) state = "welcome";
else if (which == 2) state = "working";
else if (which == 3) state = "welcome next time!";
4.State设计模式的组成
一般State设计模式由表示状态的基类及其表示各种具体状态的子类,以及状态开关管理器。
5.例子
采用c++代码实现。Context就表示开关管理器,State是各种状态的基类,BlueState为蓝色状态类,GreenState表示绿色状态类。
class Context;
class State;
class Context
{
public:
Context(void):
state(0)
{}
virtual ~Context(void)
{}
void setstate(State * state)
{
this.state = state;
}
void push(void)
{
state->handlepush(this);
...
}
void pull(void)
{
state->handlepull(this);
...
}
private:
State * state;
}
class State
{
public:
virtual ~State(void);
virtual void handlepush(Context * c) = 0;
virtual void handlepull(Context * c) = 0;
virtual int getcolor(void){return color;}
protected:
State(void);
int color;
}
class BlueState : public State
{
public:
BlueState(void):
color(1)
{}
~BlueState(void){}
void handlepush(Context * c)
{
c->setstate(new GreenState());
}
void handlepull(Context * c)
{
c->setstate(new RedState());
}
}
class GreenState : public State
{
public:
GreenState (void):
color(2)
{}
~GreenState (void){}
void handlepush(Context * c)
{
c->setstate(new BlueState());
}
void handlepull(Context * c)
{
c->setstate(new GreenState());
}
}
...
main函数中的应用则需要创建Context,并创建默认的状态,c.setstate(defaultstate)即可。
6.状态设计模式的优点
封装转换过程及枚举可能的状态,要求实现确定状态的种类。
7.延伸
State设计模式可以考虑和Observer设计模式配合使用,当被观察者发生变化时,会通知各个观察者,观察者状态就会发生变化。