状态模式代码(上篇博客超过代码限制)
class GumballMachine;
/* 抽象接口,在此接口内,糖果机的每个动作都有一个对应的方法 */
class State{
public:
virtual void insertQuarter() = 0; /* 投入25分钱 */
virtual void ejectQuarter() = 0; /* 退回25分钱 */
virtual void turnCrank() = 0; /* 转动曲柄 */
virtual void dispense() = 0; /* 发放糖果 */
};
/* 没有25分钱状态:根据状态图,当前状态只能执行"投入25分钱"的动作 */
class NoQuarterState:public State {
private:
GumballMachine *gumballMachine;
public:
NoQuarterState(GumballMachine *gumballMachine) {
this->gumballMachine = gumballMachine;
}
/* 当前状态下,可以投币,机器状态根据状态图改变 */
void insertQuarter() {
cout << "You inserted a quarter" << endl;
gumballMachine->setState(gumballMachine->getHasQuarterState());
}
/* 不恰当操作 */
void ejectQuarter() {
cout << "You have not inserted a quarter"<<endl;
}
/* 不恰当操作 */
void turnCrank() {
cout << "You turned,but there is no quarter" << endl;
}
/* 不恰当操作 */
void dispense() {
cout << "You need to pay quarter first."<<endl;
}
};
/* 有25分钱状态:根据状态图,当前状态可以执行"退回25分钱"和"转动曲柄"的动作 */
class HasQuarterState:public State {
private:
GumballMachine *gumballMachine;
public:
HasQuarterState(GumballMachine *gumballMachine) {
this->gumballMachine = gumballMachine;
}
/* 不恰当操作 */
void insertQuarter() {
cout << "You can't insert another quarter." << endl;
}
/* 当前状态下,可以退出25分钱,状态需要根据状态图改变 */
void ejectQuarter() {
cout << "Quarter returned" << endl;
gumballMachine->setState(gumballMachine->getNoQuarterState());
}
/* 当前状态下,可以转动曲柄,状态需要根据状态图改变 */
void turnCrank() {
cout << "You turned the Crank..." << endl;
gumballMachine->setState(gumballMachine->getSoldState());
}
/* 不恰当操作 */
void dispense() {
cout << "No gumball disoensed"<<endl;
}
};
/* 售出糖果状态:根据状态图,当前状态只能执行"发放糖果"的动作 */
class SoldState:public State {
private:
GumballMachine *gumballMachine;
public:
SoldState(GumballMachine *gumballMachine) {
this->gumballMachine = gumballMachine;
}
/* 不恰当操作 */
void insertQuarter() {
cout << "Pleaae wait, we're already giving you a gunball" << endl;
}
/* 不恰当操作 */
void ejectQuarter() {
cout << "Sorry, you aleady turned the crank." << endl;
}
/* 不恰当操作 */
void turnCrank() {
cout << "Turning twice doesn't get you another gunball" << endl;
}
/* 当前状态可以放糖果 */
void dispense() {
gumballMachine->releaseBall();
if (gumballMachine->getCount() > 0){
gumballMachine->setState(gumballMachine->getNoQuarterState());
} else {
gumballMachine->setState(gumballMachine->getSoldState());
}
}
};
/* 售罄状态:根据状态图,当前状态都不能执行,只有等着人员给机器装糖果 */
class SoldOutState:public State {
private:
GumballMachine *gumballMachine;
public:
SoldOutState(GumballMachine *gumballMachine) {
this->gumballMachine = gumballMachine;
}
void insertQuarter() {
cout << "you can't insert a quarter, the machine is sold out" << endl;
}
void ejectQuarter() {
cout << "you can't insert a quarter, you have not inserted a quarter yet" << endl;
}
void turnCrank() {
cout << "you turned, but there no gumballs" << endl;
}
void dispense() {
cout << "No gumball dispensed" << endl;
}
};
class GumballMachine{
private:
State *soldOutState;
State *noQuarterState;
State *hasQuarterState;
State *soldState;
State *state = soldOutState;
int count = 0;
public:
GumballMachine(int count) {
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldOutState = new SoldState(this);
this->count = count;
if (count > 0) {
state = noQuarterState;//糖果机初始状态
}
}
void insertQuarter() {
state->insertQuarter();
}
void ejectQuarter() {
state->ejectQuarter();
}
void turnCrank(){
state->turnCrank();
state->dispense();
}
void setState(State *state){
this->state = state;
}
void releaseBall(){
cout << "A gumball comes rolling out the slot"<<endl;
if (count != 0){
count = count - 1;
}
}
State* getSoldState() {
return soldState;
}
State* getHasQuarterState() {
return hasQuarterState;
}
State* getNoQuarterState() {
return noQuarterState;
}
State* getSoldOutState() {
return soldOutState;
}
int getCount(){
return count;
}
};