状态模式state pattern
定义:允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样。
举例:
有限状态自动机(FSM)是一个典型的状态不同,对输入有不同的响应(状态转移)。通常,我们实现
这类系统会使用很多的Switch/case语句,但是这种实现方式至少有以下两个问题:
1)当状态很多时,维护一组大的Switch/Case语句将是一个异常困难并且容易出错的工作。
2)状态逻辑和动作没有实现分离。在很多系统实现中,动作的实现代码直接写在状态逻辑当中。者带来的后果
就是系统的扩展性和维护得不到保证。
状态模式的类结构图:
状态模式的角色:
Context:用户对象
拥有一个State类型的成员,以标识对象的当前状态;
state:接口或基类
封装与context的特定状态相关的行为;
ConcreteState:接口实现类或子类
实现了一个与Context某个状态相关的行为。
适用场景:
通过用户的状态来改变对象的行为。
兑现代码:
#include <iostream>
using namespace std;
class Worker;
//抽象出来的状态类
class State
{
public:
virtual void doSomething(Worker*w)=0;
};
//状态管理类
class Worker
{
public:
//初始化状态
Worker();
//改变当前的状态
void setHour(int hour)
{
m_hour = hour;
}
int getHour()
{
return m_hour;
}
State*getCurrentState()
{
return m_currstate;
}
void setCurrentState(State*state)
{
m_currstate = state;
}
void doSomething()
{
m_currstate->doSomething(this);
}
private:
State*m_currstate;//对象当前的状态
int m_hour;
};
//具体的状态子类
class ConcreteStateA:public State
{
public:
void doSomething(Worker*w);
};
//具体的状态子类
class ConcreteStateB:public State
{
public:
void doSomething(Worker*w);
};
void ConcreteStateA:: doSomething(Worker*w)
{
if(w->getHour()==7||w->getHour()==8)
{
cout<<"吃早饭"<<endl;
}
else
{
delete w->getCurrentState();
w->setCurrentState(new ConcreteStateB);
w->getCurrentState()->doSomething(w);
}
}
void ConcreteStateB:: doSomething(Worker*w)
{
if(w->getHour()==9||w->getHour()==10)
{
cout<<"工作"<<endl;
}
else
{
delete w->getCurrentState();
w->setCurrentState(new ConcreteStateA);
//w->getCurrentState()->doSomething(w);
}
}
Worker::Worker()
{
m_currstate = new ConcreteStateA;
}
//初始化A状态
int main()
{
Worker *w1 = new Worker;
w1->setHour(7);
w1->doSomething();
w1->setHour(9);
w1->doSomething();
delete w1;
getchar();
return 0;
}