文章目录
前言
今天复习了状态模式,感觉平常可能用的会比较多(解决多分支问题),这里分享给大家。
1. 状态模式的理解
状态模式,就是把所有的状态抽象成一个个具体的类,然后继承一个抽象状态类,在每一个状态类内封装对应状态的行为,符合开放封闭原则,当增加新的状态或减少状态时,只需修改关联的类即可。很适合多分支行为方法的处理,这里的多分支,当然是状态比较多的情况下,如果只有小于4个状态,个人认为还是分支处理简单些。
状态模式正规的定义与类图(引用《大话设计模式》)如下所示:
2. 状态模式的C++实现
这里以一天工作中的工作状态为例实现状态模式。
工作状态的类图结构(引用《大话设计模式》)如下所示:
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;
}
总结
状态模式可以用来解决多分支问题,把复杂的问题简单化,但是对于简单的分支,就没必要使用了。
参考
《大话设计模式》