#ifndef __STATE_H__
#define __STATE_H__
//【说明】
// 状态模式和策略模式比较像,唯一的差别就是状态模式由内部提供接口给外面来进行状态的转换,而策略模式由外部来创建策略实例来调用。
// 对象如何在每一种状态下表现出不同的行为?
//【定义】
// 状态模式:允许一个对象在其内部状态改变时改变它的行为,使对象看起来似乎修改了它的类。
//【角色】
// 抽象状态(State): 定义一个接口以封装与Context的一个特定状态相关的行为。
// 具体状态(ConcreteState): 每一子类实现一个与Context的一个状态相关的行为。
// 环境类(Context): 定义客户感兴趣的接口。维护一个ConcreteState子类的实例,这个实例定义当前状态。
//【意义】
// State模式将所有与一个特定的状态相关的行为都放入一个对象中, 所以通过定义新的子类可以很容易的增加新的状态和转换。
// 如果不使用状态模式,当接口里的方法比较多时,每个方法内部都进行状态判断是一件很繁琐复杂的事情。
//【示例】
//抽象状态接口
class iState
{
public:
virtual void Proc() = 0;
};
//具体状态
class Morning : public iState
{
public:
virtual void Proc();
};
class Day : public iState
{
public:
virtual void Proc();
};
class Night : public iState
{
public:
virtual void Proc();
};
//上下文类,定义客户端使用的接口并维护一个具体状态的实例
class StateContext
{
public:
StateContext();
virtual ~StateContext();
void ChangeState(iState * state);
void SetHour(int hour);
void Execute();
private:
Morning *m_morning;
Day *m_day;
Night *m_night;
iState *m_state;
};
void TestState();
#endif
#include <stdio.h>
#include "State.h"
void Morning::Proc()
{
printf("Now is Morning. \n");
}
void Day::Proc()
{
printf("Now is Day. \n");
}
void Night::Proc()
{
printf("Now is Night. \n");
}
StateContext::StateContext()
{
m_morning = new Morning();
m_day = new Day();
m_night = new Night();
m_state = m_morning;
}
StateContext::~StateContext()
{
if (m_morning)
{
delete m_morning;
}
if (m_day)
{
delete m_day;
}
if (m_night)
{
delete m_night;
}
}
void StateContext::ChangeState(iState * state)
{
m_state = state;
}
void StateContext::SetHour(int hour)
{
if (hour < 9 && hour > 4)
{
this->ChangeState(m_morning);
}
else if (hour >= 9 && hour < 18)
{
this->ChangeState(m_day);
}
else
{
this->ChangeState(m_night);
}
}
void StateContext::Execute()
{
m_state->Proc();
}
void TestState()
{
StateContext * sc = new StateContext();
for (int hour=0; hour<23; hour++)
{
sc->SetHour(hour);
sc->Execute();
}
delete sc;
}