State状态模式
作用:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
UML图如下:
State类,抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。
ConcreteState类,具体状态,每一个子类实现一个与Context的一个状态相关的行为。
Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转换。
可以消除庞大的条件分支语句。状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式。
另外如果业务需求某项业务有多个状态,通常都是一些枚举常量,状态的变化都是依靠大量的多分支判断语句来实现,此时应该考虑将每一种业务状态定义为一个State的子类。这样这些对象就可以不依赖于其他对象儿独立变化了。
代码如下:
State.h
#ifndef _STATE_H_
#define _STATE_H_
class Context;
class State
{
public:
virtual void Handle(Context* pContext)=0;
~State();
protected:
State();
private:
};
class ConcreteStateA : public State
{
public:
ConcreteStateA();
~ConcreteStateA();
virtual void Handle(Context* pContext);
protected:
private:
};
class ConcreteStateB : public State
{
public:
ConcreteStateB();
~ConcreteStateB();
virtual void Handle(Context* pContext);
protected:
private:
};
class ConcreteStateC : public State
{
public:
ConcreteStateC();
~ConcreteStateC();
virtual void Handle(Context* pContext);
protected:
private:
};
class Context
{
public:
Context(State* pState);
~Context();
void Request();
void ChangeState(State* pState);
protected:
private:
State* _state;
};
#endif
State.cpp
#include "State.h"
#include <iostream>
using namespace std;
State::State()
{}
State::~State()
{}
ConcreteStateA::ConcreteStateA()
{}
ConcreteStateA::~ConcreteStateA()
{}
//执行该状态的行为并改变状态
void ConcreteStateA::Handle(Context* pContext)
{
cout << "ConcreteStateA" << endl;
pContext->ChangeState(new ConcreteStateB());
}
ConcreteStateB::ConcreteStateB()
{}
ConcreteStateB::~ConcreteStateB()
{}
//执行该状态的行为并改变状态
void ConcreteStateB::Handle(Context* pContext)
{
cout << "ConcreteStateB" << endl;
pContext->ChangeState(new ConcreteStateC());
}
ConcreteStateC::ConcreteStateC()
{}
ConcreteStateC::~ConcreteStateC()
{}
//执行该状态的行为并改变状态
void ConcreteStateC::Handle(Context* pContext)
{
cout << "ConcreteStateC" << endl;
pContext->ChangeState(new ConcreteStateA());
}
//定义_state的初始状态
Context::Context(State* pState)
{
this->_state = pState;
}
Context::~Context()
{}
//对请求做处理,并设置下一状态
void Context::Request()
{
if(NULL != this->_state)
{
this->_state->Handle(this);
}
}
//改变状态
void Context::ChangeState(State* pState)
{
this->_state = pState;
}
main.cpp
#include "State.h"
int main()
{
State* pState = new ConcreteStateA();
Context* pContext = new Context(pState);
pContext->Request();
pContext->Request();
pContext->Request();
pContext->Request();
pContext->Request();
return 0;
}