状态模式允许通过改变对象内部的状态而改变其行为,此时这个对象表现得就像修改了它的类一样。状态模式把所研究的对象的行为包装在不同的状态对象里,每个状态对象都属于一个抽象状态类的一个子类,当对象的状态发生变化时,对象便改变其所选的子类,从而达到修改其行为的目的。
优点: 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;
}
运行结果如下: