State Pattern状态模式(三)

来源:互联网 发布:applem2传奇引擎源码 编辑:程序博客网 时间:2024/06/08 09:40

    状态模式允许对象在内部状态改变时,改变它的行为。P410类图

#include<iostream>  using std::cout;  using std::endl;  //***********************************************  // State Interface.  //***********************************************  class State  {  public :      virtual void insertMoney() = 0;  virtual void ejectMoney() = 0;virtual void turnCrank() = 0; virtual void dispense() = 0; };  //***********************************************  // NoMoneyState implements state Interface.  //***********************************************    class  NoMoneyState : public State  { CandyMachine* candymachine; public: NoMoneyState(){ }; NoMoneyState(CandyMachine* candymachine) { this->candymachine = candymachine; }; public: void insertMoney() {cout<< "You insert money."<<endl; } virtual void dispense()  { cout<< "You need pay first."<<endl; } virtual void turnCrank()  { cout<< "You turned Crank but you haven't insert money."<<endl; } virtual void ejectMoney()  { cout<< "You haven't insert money."<<endl; } }; //***********************************************  // HasMoneyState implements state Interface.  //***********************************************     class  HasMoneyState : public State  { CandyMachine* candymachine; public: HasMoneyState(){ }; HasMoneyState(CandyMachine* candymachine) { this->candymachine = candymachine; }; public: virtual void insertMoney()  { printf("HasMoneyState_insertMoney, Already have money.\n"); } virtual void dispense()  { printf("HasMoneyState_dispense, No candy dispense.\n"); } virtual void turnCrank()  { printf("HasMoneyState_turnCrank, You turned...\n"); candymachine->setState(candymachine->getSoldState()); } virtual void ejectMoney()  { printf("HasMoneyState_ejectMoney,Money returning...\n"); candymachine->setState(candymachine->getSoldOutState()); } };//***********************************************  // SoldState implements state Interface.  //***********************************************   class  SoldState : public State  { CandyMachine* candymachine; public: SoldState() { }; SoldState(CandyMachine* candymachine) { this->candymachine = candymachine; }; public: virtual void insertMoney()  { printf("SoldState_insertMoney, Please Wait, already giving you a candy.\n"); } virtual void turnCrank()  { printf("SoldState_turnCrank, Turning twice doesn't give you more.\n"); } virtual void ejectMoney()  { printf("SoldState_ejectMoney, Sorry,you already turned the crank.\n"); } virtual void dispense()  { candymachine->releasecandy(); if (candymachine->getCount() > 0) { candymachine->setState(candymachine->getNoMoneyState()); }  else { printf("SoldState_dispense, Out of candy.\n"); candymachine->setState(candymachine->getSoldOutState()); }  } };//***********************************************  // SoldOutState implements state Interface.  //***********************************************    //class CandyMachine; // forward reference class  SoldOutState : public State  { CandyMachine* candymachine; public: SoldOutState() { }; SoldOutState(CandyMachine* candymachine) { this->candymachine = candymachine; };  public: virtual void insertMoney()  {  printf("SoldOutState_insertMoney, you can't insert, Sold Out.\n"); } virtual void dispense()  {  printf("SoldOutState_dispense, No candy to sell.\n"); } virtual void turnCrank()  {  printf("SoldOutState_ejectMoney, Out of candy..\n"); } virtual void ejectMoney()  { /*throw std::logic_error("The method or operation is not implemented.");*/  printf("SoldOutState_ejectMoney, you insert no money.\n"); } };class CandyMachine{State* noMoneyState;State* hasMoneyState;State* soldState;State* soldOutState;State* state ;int count ;public:CandyMachine(int numbercandy){noMoneyState = new NoMoneyState(this);hasMoneyState = new HasMoneyState(this);soldState = new SoldState(this);soldOutState = new SoldOutState(this);this->state = soldOutState; // Is it right if state = soldOutState?this->count = 0;this->count = numbercandy;if (numbercandy > 0){this->state = noMoneyState;}}void insertMoney(){state->insertMoney();}void ejectMoney(){state->ejectMoney();}void turnCrank(){state->turnCrank();state->dispense();}void releasecandy(){cout<< "Candy coming out!!"<<endl;if (cout != 0 ){count = count -1;}}void setState(State* state){this->state = state;}State* getNoMoneyState(){return this->noMoneyState;}State* getHasMoneyState(){return this->hasMoneyState;}State* getSoldState(){return this->soldState;}State* getSoldOutState(){return this->soldOutState;}int getCount(){return this->count;}};
因为编译原因,我把它分开了,写成了多个类

1. 前向声明(注意,不能实例化类的对象,但可以定义类类型指针State*)


2. main函数

3. 类图


总结:


1. 状态模式有点像策略模式,拥有一个接口(在这里是State接口),委托给相应子类处理。比如candymachine->insertMoney,委托后就是State.insertMoney, 这里的State就是根据不同状态去调用自己的方法,如果是NoMoneyState就调用noMoneyState.insertMoney,(因为在CandyMachine内部维护了四个状态和当前状态,保存在state变量中)。

2.  不同之处在于,在每个接口子类中,它们各自又维护了一个candymachine对象,它的作用就是用来切换状态的。例如,

void HasMoneyState::turnCrank() {printf("HasMoneyState_turnCrank, You turned...\n");candymachine->setState(candymachine->getSoldState());}
在HasMoneyState,转动手柄,就切换到了SoldState状态了。


0 0
原创粉丝点击