第十六章-状态模式

状态模式(State): 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

图片

基本代码

#include<iostream>
#include<string>
#include<vector>

using namespace std;

class Context;

class State
{
public:
	virtual void Handle(Context* context) = 0;
};

//Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态
class Context
{
private:
	State* state;
public:
	Context(State* state_t) { state = state_t; } //定义Context的初始状态

	State* get() { return state; }
	void set(State* state_t) { state = state_t; }

	void Request()   //对请求做处理,并设置下一个状态
	{
		state->Handle(this);
	}
};

class ConcreteStateA : public State
{
public:
	ConcreteStateA();
	void Handle(Context* context);   //设置ConcreteStateA的下一个状态,具体实现要写在累外面,避免顺序问题
};

class ConcreteStateB : public State
{
public:
	void Handle(Context* context)
	{
		cout << "B" << endl;
		context->set(new ConcreteStateA());
	}
};

ConcreteStateA::ConcreteStateA() {}
void ConcreteStateA:: Handle(Context* context)
{
	cout << "A" << endl;
	context->set(new ConcreteStateB());
}



int main()
{
	Context* c = new Context(new ConcreteStateA());

	c->Request();
	c->Request();
	c->Request();
	c->Request();

	system("pause");
	return 0;
}

状态模式的好处是将与特定状态相关的行为局部化,并且讲不同状态的行为分割开来。
将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转换。
状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
当一个对象的行为取决于它的状态,并且他必须在运行时时刻根据状态改变他的行为时,就可以考虑使用状态模式了。

工作状态-状态模式版

图片

//work.h

class Work;

//抽象状态
class State
{
public:
	virtual void WriteProgram(Work* w) = 0;
};

//上午工作状态类
class ForenoonState :public State
{
	void WriteProgram(Work* w);
};

//中午工作状态类
class NoonState :public State
{
	void WriteProgram(Work* w);
};

//下午工作状态类
class AfternoonState :public State
{
	void WriteProgram(Work* w);
};

//晚间工作状态类
class EveningState :public State
{
	void WriteProgram(Work* w);
};

//睡眠状态类
class SleepingState :public State
{
	void WriteProgram(Work* w);
};

//下班休息类
class RestState :public State
{
	void WriteProgram(Work* w);
};

//工作类
class Work
{
private:
	State* current;
	double hour;
	bool finish;
public:
	Work() 
		: current(new ForenoonState()), hour(0), finish(true) {}

	double getHour() { return hour; }
	void setHour(double hour_t) { hour = hour_t; }
	bool getTaskFinish() { return finish; }
	void setTaskFinish(bool finish_t) { finish = finish_t; }
	void setState(State* s) { current = s; }

	void WriteProgram()
	{
		current->WriteProgram(this);
	}
};
//work.cpp

#include<iostream>
#include"work.h"

void ForenoonState::WriteProgram(Work* w)
{
	if (w->getHour() < 12)
	{
		std::cout << "当前时间:" << w->getHour() << "点 " << "上午工作,精神百倍。" << std::endl;;
	}
	else
	{
		w->setState(new NoonState());
		w->WriteProgram();
	}
}

void NoonState::WriteProgram(Work* w)
{
	if (w->getHour() < 13)
	{
		std::cout << "当前时间:" << w->getHour() << "点 " << "饿了,午饭:犯困,午休。" << std::endl;;
	}
	else
	{
		w->setState(new AfternoonState());
		w->WriteProgram();
	}
}

void AfternoonState::WriteProgram(Work* w)
{
	if (w->getHour() < 17)
	{
		std::cout << "当前时间:" << w->getHour() << "点 " << "下午状态还不错,继续努力。" << std::endl;;
	}
	else
	{
		w->setState(new EveningState());
		w->WriteProgram();
	}
}

void EveningState::WriteProgram(Work* w)
{
	if (w->getTaskFinish())
	{
		w->setState(new RestState());
		w->WriteProgram();
	}
	else
	{
		if (w->getHour() < 21)
		{
			std::cout << "当前时间:" << w->getHour() << "点 " << "加班哦,疲劳之极。" << std::endl;;
		}
		else
		{
			w->setState(new SleepingState());
			w->WriteProgram();
		}
	}	
}

void SleepingState::WriteProgram(Work* w)
{

	std::cout << "当前时间:" << w->getHour() << "点 " << "不行了,睡着了。" << std::endl;;
}

void RestState::WriteProgram(Work* w)
{

	std::cout << "当前时间:" << w->getHour() << "点 " << "下班回家了。" << std::endl;;
}


//main.cpp

#include<iostream>
#include<string>
#include<vector>
#include"work.h"

using namespace std;

int main()
{
	Work* emergencyProjects = new Work();
	emergencyProjects->setHour(9);
	emergencyProjects->WriteProgram();
	emergencyProjects->setHour(10);
	emergencyProjects->WriteProgram();
	emergencyProjects->setHour(12);
	emergencyProjects->WriteProgram();
	emergencyProjects->setHour(13);
	emergencyProjects->WriteProgram();
	emergencyProjects->setHour(14);
	emergencyProjects->WriteProgram();
	emergencyProjects->setHour(17);

	emergencyProjects->setTaskFinish(false);

	emergencyProjects->WriteProgram();
	emergencyProjects->setHour(19);
	emergencyProjects->WriteProgram();
	emergencyProjects->setHour(22);
	emergencyProjects->WriteProgram();



	system("pause");
	return 0;
}
posted @ 2019-12-12 16:28  微风吹过165  阅读(92)  评论(0编辑  收藏  举报