状态模式
我们可以先看一个列子,某糖果机的操作如下图:
箭头表示行为,圈表示状态,每个行为产生一个状态
行为:
- 投入硬币
- 转动把手
- 退回硬币
- 发放糖果(糖果机自动完成)
状态:
- 没有钱币
- 有钱币
- 售卖糖果
- 售罄
每一个状态由一个行为产生 每一个行为又受到当前状态的影响
状态可以有共同的行为,但是具体到每一个状态下,会有具体的反应。同时一个行为后,变为另一个状态。 类图:
回到刚才的例子,糖果机代码如下:
#include <iostream>
using namespace std;
enum MState{
SOLD_OUT = 0,//售罄
NO_QUARTER = 1,//没钱
HAS_QUARTER = 2,//有钱
SOLD = 3 //售卖中
};
//糖果机
class GumballMachine;
//状态基类
class State{
public:
State(){
}
virtual ~State(){}
virtual void insertQuarter(){
cout << "You can't insert quarter" << endl;
}
virtual void ejectQuarter(){
cout << "You haven't inserted a quarter" << endl;
}
virtual void turnCrank(){
cout << "You turned, but there's no quarter" << endl;
}
virtual void dispense(){
cout << "You need to pay first" << endl;
}
void printState(){
cout << "State:" << m_name << endl;
}
public:
string m_name;
};
//无钱状态,等待用户投钱
class NoQuarterState : public State{
public:
NoQuarterState(GumballMachine* gumballMachine){
this->gumballMachine = gumballMachine;
this->m_name = "NO_QUARTER";
}
virtual ~NoQuarterState(){}
virtual void insertQuarter() {
cout << "You inserted a quarter" << endl;
gumballMachine->setHasQuraterState();
}
public:
GumballMachine* gumballMachine;
};
//有钱状态
class HasQuarterState : public State{
public:
HasQuarterState(GumballMachine* gumballMachine){
this->gumballMachine = gumballMachine;
this->m_name = "HAS_QUARTER";
}
virtual ~HasQuarterState(){}
virtual void ejectQuarter(){
cout << "Quarter returned" << endl;
gumballMachine->setNoquraterState();
}
virtual void turnCrank(){
cout << "You turned .." << endl;
gumballMachine->setSoldState();
}
public:
GumballMachine* gumballMachine;
};
//销售状态
class SoldState : public State{
public:
SoldState(GumballMachine* gumballMachine){
this->m_name = "SOLD";
this->gumballMachine = gumballMachine;
}
virtual ~SoldState(){}
virtual void dispense(){
cout << "Out of Gumballs" << endl;
gumballMachine->setNoquraterState();
}
public:
GumballMachine* gumballMachine;
};
//售罄状态
class SoldOutState : public State{
public:
SoldOutState(GumballMachine* gumballMachine){
this->m_name = "SOLD_OUT";
this->gumballMachine = gumballMachine;
}
virtual ~SoldOutState(){}
virtual void insertQuarter(){
printword();
}
virtual void ejectQuarter(){
printword();
}
virtual void turnCrank(){
printword();
}
virtual void dispense() {
printword();
}
void printword(){
cout << "The GumballMachine* has sold out" << endl;
}
public:
GumballMachine* gumballMachine;
};
//糖果机
class GumballMachine{
public:
GumballMachine(int count = 0){
this->m_count = count;
m_SoldOutState = new SoldOutState(this);
m_HasQuraterState = new HasQuarterState(this);
m_NoQuraterState = new NoQuarterState(this);
m_SoldState = new SoldState(this);
if(this->m_count == 0)
this->m_State = m_SoldOutState;
else
this->m_State = m_NoQuraterState;
}
~GumballMachine(){}
void setSoldOutState(){
m_State=m_SoldOutState;
}
void setSoldState(){
m_State=m_SoldState;
}
void setNoquraterState(){
m_State=m_NoQuraterState;
}
void setHasQuraterState(){
m_State=m_HasQuraterState;
}
void insertQuarter(){
m_State->insertQuarter();
}
void ejectQuarter(){
m_State->ejectQuarter();
}
void turnCrank(){
m_State->turnCrank();
}
void dispense() {
m_State->dispense();
}
void getState(){
m_State->printState();
}
public:
int m_count;
State* m_State;
State* m_SoldOutState;
State* m_SoldState;
State* m_HasQuraterState;
State* m_NoQuraterState;
};
int main(){
GumballMachine* gumballMachine;
gumballMachine->insertQuarter();
return 1;
}