介绍
结构:
- State——抽象状态角色
接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。 - ConcreteState——具体状态角色
每一个具体状态必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗地说,就是本状态下要做的事情,以及本状态如何过渡到其他状态。 - Context——环境角色
定义客户端需要的接口,并且负责具体状态的切换。
环境角色具有状态抽象角色定义的所有行为, 具体执行使用委托方式。 - 状态模式是行为模式之一
优点: 结构清晰; 遵循设计原则; 封装性非常好
缺点:类膨胀
应用: 行为随状态改变而改变的场景; 条件、 分支判断语句的替代者;
UML类图:
简单示例:
#ifndef SIMPLE_STATE_H
#define SIMPLE_STATE_H
#include <iostream>
using namespace std;
class Context;
/**
* @brief The State class
* State类,抽象状态类,定义-一个接口以封装与Context的一个特定状态相关的行为。
*/
class State
{
public:
void virtual Handle(Context *) = 0;
string virtual stateName() const = 0;
};
/**
* @brief The Context class
* Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。
*/
class Context
{
public:
Context(State *state)
{
m_state = state;
}
State *getState() const
{
return m_state;
}
void setState(State * state)
{
m_state = state;
cout<<"更新当前状态:"<<m_state->stateName()<<endl;
}
void request()
{
m_state->Handle(this);
}
private:
State *m_state;
};
/**
* @brief The ConcreteStateA class
* ConcreteState类,具体状态,每一个子类实现一个与Context的一一个状态相关的行为。
*/
class ConcreteStateA : public State
{
void Handle(Context *context) override;
string stateName() const override
{
return "ConcreteStateA";
}
};
class ConcreteStateB : public State
{
void Handle(Context *context) override;
string stateName() const override
{
return "ConcreteStateB";
}
};
class ConcreteStateC : public State
{
void Handle(Context *context) override;
string stateName() const override
{
return "ConcreteStateC";
}
};
void ConcreteStateA::Handle(Context *context)
{
//设置ConcreteStateA 的下一状态是ConcreteStateB
cout<<"当前状态:"<<stateName()<<endl;
context->setState( new ConcreteStateB);
}
void ConcreteStateB::Handle(Context *context)
{
//设置ConcreteStateA 的下一状态是ConcreteStateC
cout<<"当前状态:"<<stateName()<<endl;
context->setState( new ConcreteStateC);
}
void ConcreteStateC::Handle(Context *context)
{
//设置ConcreteStateA 的下一状态是ConcreteStateA
cout<<"当前状态:"<<stateName()<<endl;
context->setState( new ConcreteStateA);
}
#endif // SIMPLE_STATE_H
调用:
Context *c = new Context( new ConcreteStateA);
c->request();
c->request();
c->request();
c->request();
再来一个大话设计模式上面的示例,工作:
UML类图:
代码:
#ifndef WORK_STATE_H
#define WORK_STATE_H
#include <iostream>
using namespace std;
class Work;
/**
* @brief The State class
* 抽象状态
*/
class State
{
public:
void virtual writeProgram(Work *w) = 0;
};
/**
* @brief The ForenoonState class
* 上午工作状态
*/
class ForenoonState: public State
{
public:
void writeProgram(Work *w) override;
};
class NoonState: public State
{
public:
void writeProgram(Work *w) override;
};
class AfternoonState: public State
{
public:
void writeProgram(Work *w) override;
};
class EveningState: public State
{
public:
void writeProgram(Work *w) override;
};
class SleepingState: public State
{
public:
void writeProgram(Work *w) override;
};
class RestState: public State
{
public:
void writeProgram(Work *w) override;
};
class Work
{
public:
Work()
{
//工作初始化未上午工作状态,上午9点开始上班
m_currentState = new ForenoonState();
}
void setState(State *s)
{
m_currentState = s;
}
double getHour() const
{
return m_hour;
}
void setHour(double hour)
{
m_hour = hour;
}
bool getTaskFinished() const
{
return m_isFinished;
}
void setTaskFinished(bool finished)
{
m_isFinished = finished;
}
void writeProgram()
{
m_currentState->writeProgram(this);
}
private:
double m_hour;//钟点属性,状态转换依据。
bool m_isFinished;//任务完成属性,是否能下班的依据
State *m_currentState;
};
//上午
void ForenoonState::writeProgram(Work *w)
{
if( w->getHour() < 12 )
{
cout<<"当前时间: "<<w->getHour()<<"点上午工作,精神百倍"<<endl;
}
else
{
w->setState( new NoonState);
w->writeProgram();
}
}
//中午
void NoonState::writeProgram(Work *w)
{
if(w->getHour()<13)
{
cout<<"当前时间: "<<w->getHour()<<"点 饿了 , 吃午饭, 准备午休"<<endl;
}
else
{
w->setState(new AfternoonState);
w->writeProgram();
}
}
//下午
void AfternoonState::writeProgram(Work *w)
{
if(w->getHour()<17)
{
cout<<"当前时间: "<<w->getHour()<<"点 下午状态不错,继续努力"<<endl;
}
else
{
w->setState(new EveningState);
w->writeProgram();
}
}
//晚上
void EveningState::writeProgram(Work *w)
{
if(w->getTaskFinished())
{
w->setState(new RestState);
w->writeProgram();
}
else
{
if(w->getHour()<21)
{
cout<<"当前时间: "<<w->getHour()<<"点 加班哦,疲乏之极"<<endl;
}
else
{
w->setState(new SleepingState);
w->writeProgram();
}
}
}
//休息
void SleepingState::writeProgram(Work *w)
{
cout<<"当前时间: "<<w->getHour()<<"点 不行,扛不住了,摇睡觉。"<<endl;
}
//下班
void RestState::writeProgram(Work *w)
{
cout<<"当前时间: "<<w->getHour()<<"点 下班啦,下班啦。"<<endl;
}
#endif // WORK_STATE_H
调用:
//紧急项目
Work *emergencyProject = new Work();
emergencyProject->setHour(9.0);
emergencyProject->writeProgram();
emergencyProject->setHour(10.0);
emergencyProject->writeProgram();
emergencyProject->setHour(12.0);
emergencyProject->writeProgram();
emergencyProject->setHour(13.0);
emergencyProject->writeProgram();
emergencyProject->setHour(14.0);
emergencyProject->writeProgram();
emergencyProject->setHour(17.0);
emergencyProject->writeProgram();
emergencyProject->setTaskFinished(true);
emergencyProject->setTaskFinished(false);
emergencyProject->writeProgram();
emergencyProject->setHour(19.0);
emergencyProject->writeProgram();
emergencyProject->setHour(22);
emergencyProject->writeProgram();