Headfirst设计模式的C++实现——状态模式(State)

state.h

 #ifndef _STATE_H_
#define _STATE_H_ class GumballMachine; class State {
public:
virtual void insert_quarter() = ;
virtual void eject_quarter() = ;
virtual void turn_crank() = ;
virtual void dispense() = ;
State( GumballMachine &_gumball_machine ) : gumball_machine (_gumball_machine ) {}
protected:
GumballMachine &gumball_machine;
};
#endif

gumball_machine.h

说明:这里之所有要把SoldOutState等状态定义在GumballMachine类之中是因为两者之间有相互的依赖,暂时没有想到其他的解决方法。

 #ifndef _GUMBALL_MACHINE_H_
#define _GUMBALL_MACHINE_H_
#include <iostream>
#include "state.h" class GumballMachine {
private:
class SoldOutState : public State {
public:
SoldOutState( GumballMachine &_gumball_machine ) : State(_gumball_machine) {}
void insert_quarter() {
std::cout << "You can't insert a quarter, the machine is sold out" << std::endl;
}
void eject_quarter() {
std::cout << "you can't eject, you haven't inserted a quarter yet" << std::endl;
}
void turn_crank() {
std::cout << "You turned, but there's no gumballs" << std::endl;
}
void dispense() {
std::cout << "No gumball dispensed" << std::endl;
}
}; class NoQuarterState : public State {
public:
NoQuarterState( GumballMachine &_gumball_machine ): State(_gumball_machine) {}
void insert_quarter() {
std::cout << "You inserted a quarter" << std::endl;
gumball_machine.set_state( gumball_machine.get_has_quarter_state() );
}
void eject_quarter() {
std::cout << "You haven't inserted a quarter" << std::endl;
}
void turn_crank() {
std::cout << "You turned, but there's no quarter" << std::endl;
}
void dispense() {
std::cout << "You need to pay first" << std::endl;
}
}; class HasQuarterState : public State {
public:
HasQuarterState( GumballMachine & _gumball_machine ) : State(_gumball_machine) {}
void insert_quarter() {
std::cout << "You can't insert another quarter" << std::endl;
}
void eject_quarter() {
std::cout << "Quarter returned" << std::endl;
gumball_machine.set_state( gumball_machine.get_no_quarter_state() );
}
void turn_crank() {
std::cout << "You turned..." << std::endl;
gumball_machine.set_state( gumball_machine.get_sold_state() );
}
void dispense() {
std::cout << "No gumball dispensed" << std::endl;
}
};
class SoldState : public State {
public:
SoldState( GumballMachine &_gumball_machine ) : State(_gumball_machine) {}
void insert_quarter() {
std::cout << "Please wait, we're already giving you a gumball" << std::endl;
}
void eject_quarter() {
std::cout << "Sorry, you already turned the crank" << std::endl;
}
void turn_crank() {
std::cout << "Turning twice doesn't get you another gumball!" << std::endl;
}
void dispense() {
gumball_machine.release_ball();
if ( == gumball_machine.get_count() ) {
gumball_machine.set_state( gumball_machine.get_sold_out_state() );
}
else {
gumball_machine.set_state( gumball_machine.get_no_quarter_state() );
}
}
}; SoldOutState sold_out_state;
NoQuarterState no_quarter_state;
HasQuarterState has_quarter_state;
SoldState sold_state;
State *state;
unsigned count;
public:
GumballMachine( unsigned _count ) :
count(_count),
sold_out_state( *this ),
no_quarter_state( *this ),
has_quarter_state( *this ),
sold_state( *this ) {
if ( == count ) {
state = &sold_out_state;
}
else {
state = &no_quarter_state;
}
}
void release_ball() {
std::cout << "A gumball comes rolling out the slot" << std::endl;
count--;
if ( == count ) {
std::cout << "Oops, out of gumballs!" << std::endl;
}
}
unsigned get_count() { return count; }
void insert_quarter() { state->insert_quarter(); }
void eject_quarter() { state->eject_quarter(); }
void turn_crank() { state->turn_crank(); state->dispense(); }
void set_state( State *_state ) { state = _state; }
State *get_sold_out_state() { return &sold_out_state; }
State *get_no_quarter_state() { return &no_quarter_state; }
State *get_has_quarter_state() { return &has_quarter_state; }
State *get_sold_state() { return &sold_state; }
};
#endif

main.cpp

 #include "gumball_machine.h"

 int main() {
GumballMachine gumball_machine(); gumball_machine.insert_quarter();
gumball_machine.eject_quarter();
gumball_machine.insert_quarter();
gumball_machine.turn_crank(); gumball_machine.insert_quarter();
gumball_machine.eject_quarter();
gumball_machine.insert_quarter();
gumball_machine.turn_crank(); gumball_machine.insert_quarter();
gumball_machine.eject_quarter();
gumball_machine.insert_quarter();
gumball_machine.turn_crank();
return ;
}
上一篇:BZOJ 1800: [Ahoi2009]fly 飞行棋【思维题,n^4大暴力】


下一篇:一台服务部署多个tomcat注意事项