常見設計模式的解析和實現(C++)之十七-State模式
阿新 • • 發佈:2018-12-27
作用:
允許一個物件在其內部狀態改變時改變它的行為.
UML結構圖:
解析:
State模式主要解決的是在開發中時常遇到的根據不同的狀態需要進行不同的處理操作的問題,而這樣的問題,大部分人是採用switch-case語句進行處理的,這樣會造成一個問題:分支過多,而且如果加入一個新的狀態就需要對原來的程式碼進行編譯.State模式採用了對這些不同的狀態進行封裝的方式處理這類問題,當狀態改變的時候進行處理然後再切換到另一種狀態,也就是說把狀態的切換責任交給了具體的狀態類去負責.同時,State模式和Strategy模式在圖示上有很多相似的地方,需要說明的是兩者的思想都是一致的,只不過封裝的東西不同:State模式封裝的是不同的狀態,而Stategy模式封裝的是不同的演算法.
實現:
1)State.h
/**//********************************************************************
created: 2006/08/05
filename: State.h
author: 李創
http://www.cppblog.com/converse/
purpose: State模式的演示程式碼
*********************************************************************/
#ifndef STATE_H
#define STATE_H
class State;
class Context
{
public:
Context(State* pState);
~Context();
void Request();
void ChangeState(State *pState);
private:
State *m_pState;
};
class State
{
public:
virtual~State(){}
virtualvoid Handle(Context* pContext) =0;
};
class ConcreateStateA
: public State
{
public :
void Handle(Context* pContext);
};
class ConcreateStateB
: public State
{
public:
void Handle(Context* pContext);
};
#endif
2)State.cpp
/**//********************************************************************
created: 2006/08/05
filename: State.cpp
author: 李創
http://www.cppblog.com/converse/
purpose: State模式的演示程式碼
*********************************************************************/
#include "State.h"
#include <iostream>
Context::Context(State* pState)
: m_pState(pState)
{
}
Context::~Context()
{
delete m_pState;
m_pState = NULL;
}
void Context::Request()
{
if (NULL != m_pState)
{
m_pState->Handle(this);
}
}
void Context::ChangeState(State *pState)
{
if (NULL != m_pState)
{
delete m_pState;
m_pState = NULL;
}
m_pState = pState;
}
void ConcreateStateA::Handle(Context* pContext)
{
std::cout <<"Handle by ConcreateStateA\n";
if (NULL != pContext)
{
pContext->ChangeState(new ConcreateStateB());
}
}
void ConcreateStateB::Handle(Context* pContext)
{
std::cout <<"Handle by ConcreateStateB\n";
if (NULL != pContext)
{
pContext->ChangeState(new ConcreateStateA());
}
}
3)Main.cpp
/**//********************************************************************
created: 2006/08/05
filename: Main.cpp
author: 李創
http://www.cppblog.com/converse/
purpose: State模式的測試程式碼
*********************************************************************/
#include "State.h"
int main()
{
State *pState =new ConcreateStateA();
Context *pContext =new Context(pState);
pContext->Request();
pContext->Request();
pContext->Request();
delete pContext;
return0;
}
允許一個物件在其內部狀態改變時改變它的行為.
UML結構圖:
解析:
State模式主要解決的是在開發中時常遇到的根據不同的狀態需要進行不同的處理操作的問題,而這樣的問題,大部分人是採用switch-case語句進行處理的,這樣會造成一個問題:分支過多,而且如果加入一個新的狀態就需要對原來的程式碼進行編譯.State模式採用了對這些不同的狀態進行封裝的方式處理這類問題,當狀態改變的時候進行處理然後再切換到另一種狀態,也就是說把狀態的切換責任交給了具體的狀態類去負責.同時,State模式和Strategy模式在圖示上有很多相似的地方,需要說明的是兩者的思想都是一致的,只不過封裝的東西不同:State模式封裝的是不同的狀態,而Stategy模式封裝的是不同的演算法.
實現:
1)State.h
created: 2006/08/05
filename: State.h
author: 李創
http://www.cppblog.com/converse/
purpose: State模式的演示程式碼
*********************************************************************/
#ifndef STATE_H
#define
class State;
class Context
{
public:
Context(State* pState);
~Context();
void Request();
void ChangeState(State *pState);
private:
State *m_pState;
};
class State
{
public:
virtual~State(){}
virtualvoid Handle(Context* pContext) =0;
};
class ConcreateStateA
: public State
{
public
void Handle(Context* pContext);
};
class ConcreateStateB
: public State
{
public:
void Handle(Context* pContext);
};
#endif
2)State.cpp
/**//********************************************************************
created: 2006/08/05
filename: State.cpp
author: 李創
http://www.cppblog.com/converse/
purpose: State模式的演示程式碼
*********************************************************************/
#include "State.h"
#include <iostream>
Context::Context(State* pState)
: m_pState(pState)
{
}
Context::~Context()
{
delete m_pState;
m_pState = NULL;
}
void Context::Request()
{
if (NULL != m_pState)
{
m_pState->Handle(this);
}
}
void Context::ChangeState(State *pState)
{
if (NULL != m_pState)
{
delete m_pState;
m_pState = NULL;
}
m_pState = pState;
}
void ConcreateStateA::Handle(Context* pContext)
{
std::cout <<"Handle by ConcreateStateA\n";
if (NULL != pContext)
{
pContext->ChangeState(new ConcreateStateB());
}
}
void ConcreateStateB::Handle(Context* pContext)
{
std::cout <<"Handle by ConcreateStateB\n";
if (NULL != pContext)
{
pContext->ChangeState(new ConcreateStateA());
}
}
3)Main.cpp
/**//********************************************************************
created: 2006/08/05
filename: Main.cpp
author: 李創
http://www.cppblog.com/converse/
purpose: State模式的測試程式碼
*********************************************************************/
#include "State.h"
int main()
{
State *pState =new ConcreateStateA();
Context *pContext =new Context(pState);
pContext->Request();
pContext->Request();
pContext->Request();
delete pContext;
return0;
}