状态模式(c++实现)
状态模式
模式定义
状态模式(state),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
模式动机
- 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
- 当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式了。
UML类图
源码实现
- state.h
#include <string>
class People;
class State
{
public:
State(std::string context);
virtual ~State();
virtual void Handle(People* people) = 0;
std::string Content();
protected:
std::string m_Content;
private:
int m_Time;
};
- people.h
#include "state.h"
class People
{
public:
People(State* state);
void ChangeState(State* state);
void Show();
void SetTime(int time);
int Time();
private:
int m_Now;
State* m_State;
};
- people.cpp
#include <iostream>
#include "people.h"
People::People(State* state)
:m_State(state)
{
}
void People::ChangeState(State* state)
{
m_State = state;
}
void People::Show()
{
std::cout << "来吧,展示!" << std::endl;
std::cout << "当前状态:" << m_State->Content() << std::endl;
}
void People::SetTime(int time)
{
m_Now = time;
m_State->Handle(this);
}
int People::Time()
{
return m_Now;
}
- lifestate.h
#include "state.h"
class LifeState : public State
{
public:
LifeState(std::string content = "生活状态");
void Handle(People *people) override;
};
- lifestate.cpp
#include "lifestate.h"
#include "workstate.h"
#include "people.h"
LifeState::LifeState(std::string content)
:State(content)
{
}
void LifeState::Handle(People *people)
{
int time = people->Time();
if(time > 9 && time < 18)
people->ChangeState(new WorkState());
}
- main.cpp
#include <iostream>
#include <memory>
#include "people.h"
#include "workstate.h"
#include "playstate.h"
#include "lifestate.h"
using namespace std;
int main()
{
std::shared_ptr<State> state1 = std::make_shared<WorkState>();
People p(state1.get());
p.Show();
p.SetTime(9);
p.Show();
p.SetTime(11);
p.Show();
p.SetTime(13);
p.Show();
p.SetTime(20);
p.Show();
p.SetTime(22);
p.Show();
return 0;
}
- 运行结果
来吧,展示!
当前状态:工作状态
来吧,展示!
当前状态:工作状态
来吧,展示!
当前状态:工作状态
来吧,展示!
当前状态:玩儿乐状态
来吧,展示!
当前状态:生活状态
优点
模式的优点
-
将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易的增加新的状态和转换。
-
消除庞大的条件分支语句。
-
状态模式通过把各种状态转移逻辑分布到state的子类之间,来减少相互之间的依赖。
缺点
模式的缺点
- 每个子状态跳转到另外一个子状态是固定的,不能够灵活设置下一个状态,也就是说状态之间装换最好是一对一的,否则就又会出现一个庞大的分支语句。从这点上来看还有点像职责链模式。