狀態模式
定義:
允許一個對象在其內部狀態改變時改變它的行為。對象看起來似乎修改了它的類。
實用性:
1、 一個對象的行為取決於它的狀態,並且它必須在運行時刻根據狀態改變它的行為。
2、 一個操作中含有龐大的多分支條件陳述式,且這些分支依賴於該對象的狀態。
優點:
1、 將與特定狀態相關的行為局部化,並且將不同狀態的行為分割開來。
2、 使得狀態轉換顯示化。
3、 狀態物件可以被共用。
結構:
實現:
class Context;
class State
{
public:
State(string name):m_name(name)
{ }
virtual void Handle(Context *pContext)
{ }
virtual~State()
{ }
string GetStateName()
{
returnm_name;
}
protected:
voidChangeState(Context *pContext,State *pState);
private:
string m_name;
};
class Context
{
public:
voidRequest()
{
m_pCurrentState->Handle(this);
}
voidSetCurrentState(State *pState)
{
cout<<"設定目前狀態為 :"<GetStateName()<<endl;< p="">
m_pCurrentState = pState;
}
State *GetCurrentState()
{
cout<<"目前狀態為 :"<<m_pcurrentstate->GetStateName()<<endl;< p="">
returnm_pCurrentState;
}
protected:
friend class State;
void ChangeState(State *pState)
{
cout<<"目前狀態由 : "<<m_pcurrentstate->GetStateName()<<" 轉變為狀態:"<GetStateName()<<endl;< p="">
m_pCurrentState = pState;
}
private:
State *m_pCurrentState;
};
voidState::ChangeState(Context *pContext,State *pState)
{
pContext->ChangeState(pState);
}
//狀態子類可以共用,所以用單例模式,這裡就忽略記憶體釋放的問題了
class ConcreteStateA;
class ConcreteStateC:public State
{
public:
staticState* GetStateAInstance()
{
if(m_pInstance == NULL)
{
m_pInstance = new ConcreteStateC("狀態 C");
}
returnm_pInstance;
}
voidHandle(Context *pContext);
private:
ConcreteStateC(string name):State(name)
{ }
staticConcreteStateC *m_pInstance;
};
class ConcreteStateB:public State
{
public:
staticState* GetStateAInstance()
{
if(m_pInstance == NULL)
{
m_pInstance = new ConcreteStateB("狀態 B");
}
returnm_pInstance;
}
voidHandle(Context *pContext)
{
cout<<"狀態 B 處理的商務邏輯"<<endl;< p="">
ChangeState(pContext,ConcreteStateC::GetStateAInstance());
}
private:
ConcreteStateB(string name):State(name)
{ }
staticConcreteStateB *m_pInstance;
};
class ConcreteStateA:public State
{
public:
staticState* GetStateAInstance()
{
if(m_pInstance == NULL)
{
m_pInstance = new ConcreteStateA("狀態 A");
}
returnm_pInstance;
}
voidHandle(Context *pContext)
{
cout<<"狀態 A 處理的商務邏輯"<<endl;< p="">
ChangeState(pContext,ConcreteStateB::GetStateAInstance());
}
private:
ConcreteStateA(string name):State(name)
{ }
staticConcreteStateA *m_pInstance;
};
voidConcreteStateC::Handle(Context *pContext)
{
cout<<"狀態 C 處理的商務邏輯"<<endl;< p="">
ChangeState(pContext,ConcreteStateA::GetStateAInstance());
}
ConcreteStateA*ConcreteStateA::m_pInstance = NULL;
ConcreteStateB*ConcreteStateB::m_pInstance = NULL;
ConcreteStateC*ConcreteStateC::m_pInstance = NULL;
Context *pContext = new Context;
pContext->SetCurrentState(ConcreteStateA::GetStateAInstance());
pContext->Request();
pContext->Request();
pContext->Request();