状态模式
概念
State模式也叫状态模式,是行为设计模式的一种。State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样。
状态模式主要解决的是:控制一个对象的状态进行转换的条件表达式,过于复杂时的情况(条件表达式控制着对象状态的转换)。把状态的判断逻辑转移到到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化。
角色及职责
Context:用户对象
拥有一个State类型的成员,以标识对象的当前状态;State:抽象状态类
封装与Context的特定状态相关的行为接口; –同时状态类完成任务的行为函数需要一个上下文环境/用户对象做参数。ConcreteState:具体状态类
实现了一个与Context某个状态相关的具体行为。
适用于:
对象的行为,依赖于它所处的当前状态。行为随状态改变而改变的场景。
案例
/*******************************
*解决--表示对象状态的表达式复杂的情况
* --大量的case语句
* --case与具体行为又相互包裹在一起
* --不能将逻辑和行为实现很好的分离
* --这列问题适合用状态模式解决
*
* 一个状态类对应于一个case语句应该有的行为
* --多个具体的状态类有一个共同的基类--抽象状态类
* --多态
*
* 抽象状态类有提供给用户对象/上下文环境使用,表示当前对象的状态
* --一般来说抽象类都有一个公共接口,子类需要实现--执行具体行为
*
* 上下文环境通过自己的状态类成员变量决定执行什么操作以对应状态对象的逻辑
*
*******************************/
#include <iostream>
#include <string>
using namespace std;
class Worker;
class State1;
class State2;
class State;
/*抽象状态类*/
class State
{
public:
virtual void doSomething(Worker *w) = 0;
};
/*上下文环境--用户对象--他的状态会改变--对应不同的行为*/
class Worker
{
public:
Worker();
void doThing()//核心函数--用户对象执行自己的行为--引起状态类成员函数的执行--状态不同--行为不同
{
m_curstate->doSomething(this);
}
int getHour()
{
return m_hour;
}
void setHour(int hour)
{
m_hour = hour;
}
State * getState()
{
return m_curstate;
}
void setState(State * state)
{
m_curstate = state;
}
private:
int m_hour;
State * m_curstate;
};
/*具体状态类--因为在行为函数里面要使用到State2的实例,但此时没有给出State2的完整实现
--所以需要先进性声明,在State2完整实现以后再进行函数的实现*/
class State1:public State
{
public:
virtual void doSomething(Worker *w);
};
/*具体状态类*/
class State2:public State
{
public:
virtual void doSomething(Worker *w);
};
/*具体状态类的行为函数的实现*/
void State1::doSomething(Worker *w)
{
if(w->getHour() == 7 || w->getHour() == 8)
{
cout<<"eating!"<<endl;
}\
else
{
delete w->getState();
w->setState(new State2);//进入下一个状态
w->getState()->doSomething(w);
}
}
/*具体状态类的行为函数的实现*/
void State2::doSomething(Worker *w)
{
if(w->getHour() == 9 || w->getHour() == 8)
{
cout<<"working!"<<endl;//具体行为--和逻辑分离
}\
else
{
delete w->getState();//不满足状态2要进入下一个状态
w->setState(new State1);//后面没有更多的状态。返回到第一个状态,否则一直进入下一个状态
cout<<"error! coming to the initial state"<<endl;
}
}
/*用户对象的构造函数--需要用到State1--所以后置实现*/
Worker::Worker()
{
m_curstate = new State1;
}
/*测试案例*/
int main()
{
Worker *w1 = new Worker;
w1->setHour(7);
w1->doThing();
w1->setHour(9);
w1->doThing();
w1->setState(new State2);
w1->setHour(7);
w1->doThing();
delete w1;
return 0;
}