状态模式允许通过改变对象内部的状态而改变其行为,此时这个对象表现得就像修改了它的类一样。状态模式把所研究的对象的行为包装在不同的状态对象里,每个状态对象都属于一个抽象状态类的一个子类,当对象的状态发生变化时,对象便改变其所选的子类,从而达到修改其行为的目的。

优点: 1、封装了转换规则。 2、枚举可能的状态,在枚举状态之前需要确定状态种类。 3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。 4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。 5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

缺点: 1、状态模式的使用必然会增加系统类和对象的个数。 2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。 3、状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。

类图如下:


示例代码如下:

#include <iostream>
#include <string>
#include <queue>

using namespace std;
class Work;
class State;
class ForenonnState;

class State
{
public:
	virtual void writeProgram(Work* w) = 0;
};
class Work
{
public:
	int hour;
	State* current;
	Work();
	void writeWork()
	{
		current->writeProgram(this);
	}
};
class EveningState:public State
{
public:
	virtual void writeProgram(Work* w)
	{
		cout<<"当前时间是:"<<w->hour<<"点,可以看看星星"<<endl;
	}

};

class AfternoonState :public State
{
public:
	virtual void writeProgram(Work* w)
	{
		if(w->hour < 19)
		{
			cout << "当前时间是:" << w->hour << "点,可以喝一点下午茶" << endl;
		}
		else
		{
			w->current = new EveningState();
			w->writeWork();
		}
	}

};
class ForenonnState :public State
{
public:
	virtual void writeProgram(Work* w)
	{
		if (w->hour < 12)
		{
			cout << "当前时间是:" << w->hour << "点,可以吃早饭" << endl;
		}
		else
		{
			w->current = new AfternoonState();
			w->writeWork();
		}
	}

};
Work::Work()
{
	current = new ForenonnState();
}
int main()
{
	Work* w = new Work();
	w->hour = 8;
	w->writeWork();

	w->hour = 15;
	w->writeWork();

	w->hour = 20;
	w->writeWork();

	delete w;
	system("pause");

	return 0;
}

运行结果如下: