今天复习了状态模式,感觉平常可能用的会比较多(解决多分支问题),这里分享给大家。
状态模式,就是把所有的状态抽象成一个个具体的类,然后继承一个抽象状态类,在每一个状态类内封装对应状态的行为,符合开放封闭原则,当增加新的状态或减少状态时,只需修改关联的类即可。很适合多分支行为方法的处理,这里的多分支,当然是状态比较多的情况下,如果只有小于4个状态,个人认为还是分支处理简单些。
状态模式正规的定义与类图(引用《大话设计模式》)如下所示:
这里以一天工作中的工作状态为例实现状态模式。
工作状态的类图结构(引用《大话设计模式》)如下所示:
C++代码实现如下:
#include <iostream> #include <memory> //*********************State Pattern******************* class Work; //抽象状态类 class State { public: virtual void WriteProgram(Work* ptrWork) = 0; }; //工作类 class Work { private: std::shared_ptr<State> smartState; double hour; bool finish; public: Work() : hour(0), finish(false), smartState(NULL) {} void SetHour(const double h) { hour = h; } double GetHour() const { return hour; } void SetFinish(bool bFinish) { finish = bFinish; } bool GetFinish() const { return finish; } void SetState(std::shared_ptr<State> pState) { smartState = pState; } std::shared_ptr<State> GetState() const { return smartState; } void WriteProgram() { smartState->WriteProgram(this); } }; //睡眠状态 class SleepingState : public State { public: void WriteProgram(Work* ptrWork) { std::cout << "当前时间:" << ptrWork->GetHour() << "点 撑不住了,睡觉吧!" << std::endl; } }; //下班休息状态 class RestState : public State { public: void WriteProgram(Work* ptrWork) { std::cout << "当前时间:" << ptrWork->GetHour() << "点 下班回家了!" << std::endl; } }; //傍晚工作状态 class EveningState : public State { public: void WriteProgram(Work* ptrWork) { if (ptrWork->GetFinish()) { ptrWork->SetState(std::make_shared<RestState>()); ptrWork->WriteProgram(); return; } if (ptrWork->GetHour() < 21) { std::cout << "当前时间:" << ptrWork->GetHour() << "点 加班吆,疲惫啊!" << std::endl; } else {//超过21点,转换到睡眠状态 ptrWork->SetState(std::make_shared<SleepingState>()); ptrWork->WriteProgram(); } } }; //下午工作状态 class AfternoonState : public State { public: void WriteProgram(Work* ptrWork) { if (ptrWork->GetHour() < 17) { std::cout << "当前时间:" << ptrWork->GetHour() << "点 下午状态还不错,继续努力!" << std::endl; } else {//超过17点,转换傍晚工作状态 ptrWork->SetState(std::make_shared<EveningState>()); ptrWork->WriteProgram(); } } }; //中午工作状态 class NoonState : public State { public: void WriteProgram(Work* ptrWork) { if (ptrWork->GetHour() < 13) { std::cout << "当前时间:" << ptrWork->GetHour() << "点 饿了,午饭,犯困,午休!" << std::endl; } else {//超过13点,转换下午工作状态 ptrWork->SetState(std::make_shared<AfternoonState>()); ptrWork->WriteProgram(); } } }; //上午工作状态类 class ForenoonState : public State { public: void WriteProgram(Work* ptrWork) { if (ptrWork->GetHour() < 12) { std::cout << "当前时间:" << ptrWork->GetHour() << "点 上午工作,精神百倍!" << std::endl; } else {//超过12点,转换中午工作状态 ptrWork->SetState(std::make_shared<NoonState>()); ptrWork->WriteProgram(); } } }; //************************Test************************** int main() { std::shared_ptr<Work> work = std::make_shared<Work>(); work->SetState(std::make_shared<ForenoonState>()); work->SetHour(9); work->WriteProgram(); work->SetHour(10); work->WriteProgram(); work->SetHour(12); work->WriteProgram(); work->SetHour(13); work->WriteProgram(); work->SetHour(14); work->WriteProgram(); work->SetHour(17); work->WriteProgram(); work->SetFinish(false); //work->SetFinish(true); //work->WriteProgram(); work->SetHour(19); work->WriteProgram(); work->SetHour(22); work->WriteProgram(); system("pause"); return 0; }
状态模式可以用来解决多分支问题,把复杂的问题简单化,但是对于简单的分支,就没必要使用了。
《大话设计模式》