state 模式(c++ 实现)


state模式:水蒸汽和冰都是水在不同温度下的状态。将 水,冰,水蒸汽,每种形态看做一种类型。将常温,加热到100度,零下10度,看成是三个动作。

对于水,冰,水蒸汽这三个类来说,对于三个动作都有分别的反应,并且在特定条件下,会变身成其他的类型。例如 水 在 加热到100度 的时候会变身成 水蒸汽。


对于一瓶水来说,我们只需要记录“当前的状态”,然后调用 三个动作的序列,通过 “当前的状态”在不同动作下自身的变化,就能得到最终 这瓶水 的 形态了。



#include <stdio.h>

#define SOLD_OUT	(0)
#define NO_QUARTER	(1)
#define HAS_QUARTER (0)
#define SOLD		(3)


class GamballMachine
{
	int state;
	int count;

public :GamballMachine(int count)
	{
		this->count = count;
		if (count > 0)
		{
			state = NO_QUARTER;
		}
	}

	void insert_quarter()
	{
		if (state == HAS_QUARTER)
		{
			printf("you can't insert another quarter.\n");
		}
		else if (state == NO_QUARTER)
		{
			state = HAS_QUARTER;
			printf("you inserted a quarter.\n");
		}
		else if (state == SOLD_OUT)
		{
			printf("you can't insert a quarter, the machine is sold out.\n");
		}
		else if (state == SOLD)
		{
			printf("please wait, we're already giving you a gamball.\n");
		}
	}

	void eject_quarter()
	{
		if (state == HAS_QUARTER)
		{
			printf("quarter returned.\n");
			state = NO_QUARTER;
		}
		else if (state == NO_QUARTER)
		{
			printf("you haven't inserted a quarter.\n");
		}
		else if (state == SOLD_OUT)
		{
			printf("you can't eject, you haven't inserted a quarter yet.\n");
		}
		else if (state == SOLD)
		{
			printf("sorry. you already turned the crank.\n");
		}
	}

	void turn_crank()
	{
		if (state == HAS_QUARTER)
		{
			printf("you turned.\n");
			state = SOLD;
			dispense();

		}
		else if (state == NO_QUARTER)
		{
			printf("you turned, but there is no quarter.\n");
		}
		else if (state == SOLD_OUT)
		{
			printf("you turned, but there is no gamballs.\n");
		}
		else if (state == SOLD)
		{
			printf("the gamball is solding, turned again doesn't take effect.\n");
		}
	}
	void dispense()
	{
		if (state == HAS_QUARTER)
		{
			printf("no gamball dispensed.\n");
		}
		else if (state == NO_QUARTER)
		{
			printf("you need to pay first.\n");
		}
		else if (state == SOLD_OUT)
		{
			printf("no gamball dispensed.\n");
		}
		else if (state == SOLD)
		{
			printf("a gamball comes rolling out of the slot.\n");
			count = count - 1;
			if (count == 0)
			{
				state = SOLD_OUT;
			}
			else
			{
				state = NO_QUARTER;
			}
		}
	}

};


int gamball_machine_test()
{
	printf("\n\n===========gamball_machine test=======\n\n");
	GamballMachine gamball_machine = GamballMachine(5);
	gamball_machine.insert_quarter();
	gamball_machine.turn_crank();

	printf("\n\n");

	gamball_machine.insert_quarter();
	gamball_machine.eject_quarter();
	gamball_machine.turn_crank();
	return 1;
}



//use state pattern to rewrite
class State
{
public :
	virtual int insert_quarter() = 0;
	virtual int eject_quarter() = 0;
	virtual int turn_crank() = 0;
	virtual int dispense() = 0;
};



class HasQuarter_State;
class NoQuarter_State;
class Soldout_State;
class Sold_State;

class GamballMachine_New
{
public:
	State *has_quarter_state;
	State  *no_quarter_state;
	State  *soldout_state;
	State  *sold_state;
	State  *state;
	int count;
public:
	GamballMachine_New(int count);
public:
	int set_state(State *state);
	HasQuarter_State *get_has_quarter_state();
	NoQuarter_State *get_no_quarter_state();
	Soldout_State *get_soldout_state();
	Sold_State *get_sold_state();
	int insert_quarter();
	int eject_quarter();
	int turn_crank();
	int dispense();
};
class HasQuarter_State:public State
{
public:	
	GamballMachine_New *gamball_machine;

public:	HasQuarter_State(GamballMachine_New *gamball_machine)
	{
		this->gamball_machine = gamball_machine;
	}

	int insert_quarter()
	{
		printf("you can't insert another quarter.\n");
		return 0;
	}

	int eject_quarter()
	{
		printf("quarter returned.\n");
		gamball_machine->set_state((State *)gamball_machine->get_no_quarter_state());
		return 0;
	}

	int turn_crank()
	{
		printf("you turned.\n");
		gamball_machine->set_state((State *)gamball_machine->get_sold_state());
		gamball_machine->dispense();
		return 0;
	}

	int dispense()
	{
		printf("no gamball dispensed.\n");
		return 0;
	}
};

class NoQuarter_State:public State
{
public:	
	GamballMachine_New *gamball_machine;
public:
	NoQuarter_State(GamballMachine_New *gamball_machine)
	{
		this->gamball_machine = gamball_machine;
	}

	int insert_quarter()
	{
		gamball_machine->set_state(gamball_machine->get_has_quarter_state());
		printf("you inserted a quarter.\n");
		return 0;
	}

	int eject_quarter()
	{
		printf("you haven't inserted a quarter.\n");
		return 0;
	}

	int turn_crank()
	{
		printf("you turned, but there is no quarter.\n");
		return 0;

	}

	int dispense()
	{
		printf("you need to pay first.\n");
		return 0;
	}
};

class Soldout_State:public State
{
	GamballMachine_New *gamball_machine;
public:
	Soldout_State(GamballMachine_New *gamball_machine)
	{
		this->gamball_machine = gamball_machine;
	}

	int insert_quarter()
	{
		printf("you can't insert a quarter, the machine is sold out.\n");
		return 0;
	}

	int eject_quarter()
	{
		printf("you can't eject, you haven't inserted a quarter yet.\n");
		return 0;
	}

	int turn_crank()
	{
		printf("you turned, but there is no gamballs.\n");
		return 0;

	}

	int dispense()
	{
		printf("no gamball dispensed.\n");
		return 0;
	}
};

class Sold_State:public State
{
	GamballMachine_New *gamball_machine;
public:
	Sold_State(GamballMachine_New *gamball_machine)
	{
		this->gamball_machine = gamball_machine;
	}

	int insert_quarter()
	{
		printf("please wait, we're already giving you a gamball.\n");
		return 0;
	}

	int eject_quarter()
	{
		printf("sorry. you already turned the crank.\n");
		return 0;
	}

	int turn_crank()
	{
		printf("the gamball is solding, turned again doesn't take effect.\n");

		return 0;
	}

	int dispense()
	{
		printf("a gamball comes rolling out of the slot.\n");
		gamball_machine->count = gamball_machine->count - 1;
		if (gamball_machine->count == 0)
		{
			gamball_machine->set_state(gamball_machine->get_soldout_state());
		}
		else
		{
			gamball_machine->set_state(gamball_machine->get_no_quarter_state());
		}
		return 0;
	}
};


GamballMachine_New::GamballMachine_New(int count)
	{
		this->state = (new NoQuarter_State(this));
		this->has_quarter_state = (new HasQuarter_State(this)) ;
		this->no_quarter_state = (new NoQuarter_State(this));
		this->soldout_state = (new Soldout_State(this));
		this->sold_state = (new Sold_State(this));
		this->count = count;
	}


int GamballMachine_New::set_state(State *state)
	{
		this->state = state;
		return 0;
	}

HasQuarter_State* GamballMachine_New::get_has_quarter_state()
	{
		return (HasQuarter_State*)has_quarter_state;
	}

NoQuarter_State* GamballMachine_New::get_no_quarter_state()
	{
		return (NoQuarter_State*)no_quarter_state;
	}

Soldout_State* GamballMachine_New::get_soldout_state()
	{
		return (Soldout_State*)soldout_state;
	}

Sold_State* GamballMachine_New::get_sold_state()
	{
		return (Sold_State*)sold_state;
	}



int GamballMachine_New::insert_quarter()
	{
		this->state->insert_quarter();
		return 0;
	}

int GamballMachine_New::eject_quarter()
	{
		this->state->eject_quarter();
		return 0;
	}

int GamballMachine_New::turn_crank()
	{
		this->state->turn_crank();
		return 0;
	}

int GamballMachine_New::dispense()
	{
		this->state->dispense();
		return 0;
	}

int gamball_machine_new_test()
{
	printf("\n\n===========gamball_machine use state pattern test=======\n\n");
	GamballMachine_New gamball_machine = GamballMachine_New(5);
	gamball_machine.insert_quarter();
	gamball_machine.turn_crank();

	printf("\n\n");

	gamball_machine.insert_quarter();
	gamball_machine.eject_quarter();
	gamball_machine.turn_crank();
	return 1;
}

int main()
{
	gamball_machine_test();
	gamball_machine_new_test();


	getchar();
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值