State mode: allows an object to change its behavior when the internal state changes, and the object looks as if it has modified its class.
Process-oriented approach: for actions, switch/if-else each state during processing, and then handle each of the following:
#include <iostream>
classGumballmachine
{
Public:
Gumballmachine ()
{
_count = -;
_state = no_quarter;
}
/ * when performing an action, Switch/if-else handles all the states * /
voidInsertquarter ()
{
Switch(_state)
{
CaseSold_out:
std::cout<<"You can ' t insert a quarter and the machine have sold out."<<std::endl;
Break;
CaseNo_quarter:
std::cout<<"Accept Coin"<<std::endl;
std::cout<<"You inserted a quarter."<<std::endl;
Break;
CaseHas_quarter:
std::cout<<"You can ' t insert another quarter."<<std::endl;
Break;
CaseSOLD:
std::cout<<"Please wait, we ' re already giving you a gumball"<<std::endl;
Break;
default:
Break;
}
}
voidEjectquarter () {}
voidTurncrank () {}
voidDispense () {}
Private:
enumMachine_state
{
Sold_out =0,
No_quarter,
Has_quarter,
SOLD,
} ;
Machine_state _state;
int_count;
};
intMain ()
{
std::cout<<"State Patten."<<std::endl;
Gumballmachine Gumballmachine;
Gumballmachine.insertquarter ();
return0;
}
Object-oriented approach: Use state mode, encapsulate each state as a class, and each class supports all actions. When used, delegates the action to the State class processing.
. h
/ * State interface for status mode * /
class State
{
Public:
VirtualvoidInsertquarter () =0;
Virtual voidEjectquarter () =0;
VirtualvoidTurncrank () =0;//Turning Crank
VirtualvoidDispense () =0;//Distribution
};
classGumballmachine
{
Public:
Gumballmachine ();
voidInsertquarter ();
voidSetState (state *state);
State *getnoquarterstate ();
State *gethasquarterstate ();
Private:
State *_noquarterstate;
State *_hasquarterstate;
State *_state;
int_count;
};
. C
#include <iostream>
#include"Main.h"
/ * various status classes * /
class noquarterstate: Public State
{
Public:
Noquarterstate (Gumballmachine *pmachine): _pgumballmachine (Pmachine)
{}
VirtualvoidInsertquarter ()
{
std::cout<<"Accept Coin"<<std::endl;
std::cout<<"You inserted a quarter."<<std::endl;
//Toggle Status
_pgumballmachine->setstate (_pgumballmachine->gethasquarterstate ());
}
VirtualvoidEjectquarter ()
{
std::cout<<"Invalid Action."<<std::endl;
}
VirtualvoidTurncrank ()
{
std::cout<<"Invalid Action."<<std::endl;
}
VirtualvoidDispense ()
{
std::cout<<"Invalid Action."<<std::endl;
}
Private:
Gumballmachine *_pgumballmachine;
};
class quarterstate: Public State
{
Public:
Quarterstate (Gumballmachine *pmachine): _pgumballmachine (Pmachine)
{}
VirtualvoidInsertquarter ()
{
std::cout<<"Invalid Action."<<std::endl;
}
VirtualvoidEjectquarter ()
{
std::cout<<"Quarter returned."<<std::endl;
//Toggle Status
_pgumballmachine->setstate (_pgumballmachine->getnoquarterstate ());
}
VirtualvoidTurncrank ()
{
std::cout<<"Crank truned."<<std::endl;
//Toggle Status ...
_pgumballmachine->setstate (_pgumballmachine->getnoquarterstate ());
}
VirtualvoidDispense ()
{
std::cout<<"Invalid Action."<<std::endl;
}
Private:
Gumballmachine *_pgumballmachine;
};
//Class Soldstate:public State
//class Soldoutstate:public state
Gumballmachine::gumballmachine ()
{
_noquarterstate =NewNoquarterstate ( This);
_hasquarterstate =NewQuarterstate ( This);
_count = -;
_state = _noquarterstate;
}
/ * Delegate to the State class when performing an action * /
voidGumballmachine::insertquarter ()
{
_state->insertquarter ();
}
voidGumballmachine::setstate (state *state)
{
_state = State;
}
State *gumballmachine::getnoquarterstate ()
{
return_noquarterstate;
}
State *gumballmachine::gethasquarterstate ()
{
return_hasquarterstate;
}
intMain ()
{
std::cout<<"State Patten."<<std::endl;
Gumballmachine Gumballmachine;
Gumballmachine.insertquarter ();
return0;
}
State mode--learning headfirst design pattern recording