转自:http://www.cnblogs.com/wanggary/archive/2011/04/21/2024117.html
概念:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
main(),客户
CLiftState,电梯状态抽象类
CCloseingState,电梯门关闭
COpenningState,电梯门打开
CRunningState,电梯运行
CStoppingState,电梯停止
CContext,电梯的控制面板
说明:CContext保持电梯的状态,并提供操作的接口函数。当函数被调用时,CContext直接调用当前状态的相应函数。由状态的接口函数来确定是否可以执行这个动作,以及修改状态为执行这个动作后的状态。
看代码:第一块是不使用模式的做法,第二块是使用模式的做法,在main()函数里会有调用的方式。
// ILift.h #pragma once class ILift { public : ILift( void ) { } virtual ~ ILift( void ) { } static const int OPENING_STATE = 1 ; static const int CLOSING_STATE = 2 ; static const int RUNNING_STATE = 3 ; static const int STOPPING_STATE = 4 ; virtual void SetState( int state) = 0 ; virtual void Open() = 0 ; virtual void Close() = 0 ; virtual void Run() = 0 ; virtual void Stop() = 0 ; }; // Lift.h #pragma once #include " ilift.h " class CLift : public ILift { public : CLift( void ); ~ CLift( void ); void SetState( int state); void Open(); void Close(); void Run(); void Stop(); private : int m_state; void OpenWithoutLogic(); void CloseWithoutLogic(); void RunWithoutLogic(); void StopWithoutLogic(); }; // Lift.cpp #include " StdAfx.h " #include " Lift.h " #include < iostream > using std::cout; using std::endl; CLift::CLift( void ) { this -> m_state = 0 ; } CLift:: ~ CLift( void ) { } void CLift::SetState( int state) { this -> m_state = state; } void CLift::Open() { switch ( this -> m_state) { case OPENING_STATE: break ; case CLOSING_STATE: this -> OpenWithoutLogic(); this -> SetState(OPENING_STATE); break ; case RUNNING_STATE: break ; case STOPPING_STATE: this -> OpenWithoutLogic(); this -> SetState(OPENING_STATE); break ; } } void CLift::Close() { switch ( this -> m_state) { case OPENING_STATE: this -> CloseWithoutLogic(); this -> SetState(CLOSING_STATE); break ; case CLOSING_STATE: break ; case RUNNING_STATE: break ; case STOPPING_STATE: break ; } } void CLift::Run() { switch ( this -> m_state) { case OPENING_STATE: break ; case CLOSING_STATE: this -> RunWithoutLogic(); this -> SetState(RUNNING_STATE); break ; case RUNNING_STATE: break ; case STOPPING_STATE: this -> RunWithoutLogic(); this -> SetState(RUNNING_STATE); break ; } } void CLift::Stop() { switch ( this -> m_state) { case OPENING_STATE: break ; case CLOSING_STATE: this -> StopWithoutLogic(); this -> SetState(CLOSING_STATE); break ; case RUNNING_STATE: this -> StopWithoutLogic(); this -> SetState(CLOSING_STATE); break ; case STOPPING_STATE: break ; } } void CLift::OpenWithoutLogic() { cout << " 电梯门开启... " << endl; } void CLift::CloseWithoutLogic() { cout << " 电梯门关闭... " << endl; } void CLift::RunWithoutLogic() { cout << " 电梯上下跑起来... " << endl; } void CLift::StopWithoutLogic() { cout << " 电梯停止了... " << endl; }
// LiftState.h #pragma once class CContext; class CLiftState { public : CLiftState( void ); virtual ~ CLiftState( void ); void SetContext(CContext * pContext); virtual void Open() = 0 ; virtual void Close() = 0 ; virtual void Run() = 0 ; virtual void Stop() = 0 ; protected : CContext * m_pContext; }; // LiftState.cpp #include " StdAfx.h " #include " LiftState.h " CLiftState::CLiftState( void ) { } CLiftState:: ~ CLiftState( void ) { } void CLiftState::SetContext( CContext * pContext ) { m_pContext = pContext; } // CloseingState.h #pragma once #include " liftstate.h " class CCloseingState : public CLiftState { public : CCloseingState( void ); ~ CCloseingState( void ); void Open(); void Close(); void Run(); void Stop(); }; // CloseingState.cpp #include " StdAfx.h " #include " CloseingState.h " #include " Context.h " #include < iostream > using std::cout; using std::endl; CCloseingState::CCloseingState( void ) { } CCloseingState:: ~ CCloseingState( void ) { } void CCloseingState::Open() { this -> CLiftState::m_pContext -> SetLiftState(CContext::pOpenningState); this -> CLiftState::m_pContext -> GetLiftState() -> Open(); } void CCloseingState::Close() { cout << " 电梯门关闭... " << endl; } void CCloseingState::Run() { this -> CLiftState::m_pContext -> SetLiftState(CContext::pRunningState); this -> CLiftState::m_pContext -> GetLiftState() -> Run(); } void CCloseingState::Stop() { this -> CLiftState::m_pContext -> SetLiftState(CContext::pStoppingState); this -> CLiftState::m_pContext -> GetLiftState() -> Stop(); } // OpenningState.h #pragma once #include " liftstate.h " class COpenningState : public CLiftState { public : COpenningState( void ); ~ COpenningState( void ); void Open(); void Close(); void Run(); void Stop(); }; // OpenningState.cpp #include " StdAfx.h " #include " OpenningState.h " #include " Context.h " #include < iostream > using std::cout; using std::endl; COpenningState::COpenningState( void ) { } COpenningState:: ~ COpenningState( void ) { } void COpenningState::Open() { cout << " 电梯门开启... " << endl; } void COpenningState::Close() { this -> CLiftState::m_pContext -> SetLiftState(CContext::pCloseingState); this -> CLiftState::m_pContext -> GetLiftState() -> Close(); } void COpenningState::Run() { // do nothing } void COpenningState::Stop() { // do nothing } // RunningState.h #pragma once #include " liftstate.h " class CRunningState : public CLiftState { public : CRunningState( void ); ~ CRunningState( void ); void Open(); void Close(); void Run(); void Stop(); }; // RunningState.cpp #include " StdAfx.h " #include " RunningState.h " #include " Context.h " #include < iostream > using std::cout; using std::endl; CRunningState::CRunningState( void ) { } CRunningState:: ~ CRunningState( void ) { } void CRunningState::Open() { // do nothing } void CRunningState::Close() { // do nothing } void CRunningState::Run() { cout << " 电梯上下跑... " << endl; } void CRunningState::Stop() { this -> CLiftState::m_pContext -> SetLiftState(CContext::pStoppingState); this -> CLiftState::m_pContext -> GetLiftState() -> Stop(); } // StoppingState.h #pragma once #include " liftstate.h " class CStoppingState : public CLiftState { public : CStoppingState( void ); ~ CStoppingState( void ); void Open(); void Close(); void Run(); void Stop(); }; // StoppingState.cpp #include " StdAfx.h " #include " StoppingState.h " #include " Context.h " #include < iostream > using std::cout; using std::endl; CStoppingState::CStoppingState( void ) { } CStoppingState:: ~ CStoppingState( void ) { } void CStoppingState::Open() { this -> CLiftState::m_pContext -> SetLiftState(CContext::pOpenningState); this -> CLiftState::m_pContext -> GetLiftState() -> Open(); } void CStoppingState::Close() { // do nothing } void CStoppingState::Run() { this -> CLiftState::m_pContext -> SetLiftState(CContext::pRunningState); this -> CLiftState::m_pContext -> GetLiftState() -> Run(); } void CStoppingState::Stop() { cout << " 电梯停止了... " << endl; }
// Contex.h #pragma once #include " LiftState.h " #include " OpenningState.h " #include " CloseingState.h " #include " RunningState.h " #include " StoppingState.h " class CContext { public : CContext( void ); ~ CContext( void ); static COpenningState * pOpenningState; static CCloseingState * pCloseingState; static CRunningState * pRunningState; static CStoppingState * pStoppingState; CLiftState * GetLiftState(); void SetLiftState(CLiftState * pLiftState); void Open(); void Close(); void Run(); void Stop(); private : CLiftState * m_pLiftState; }; // Context.cpp #include " StdAfx.h " #include " Context.h " COpenningState * CContext::pOpenningState = NULL; CCloseingState * CContext::pCloseingState = NULL; CRunningState * CContext::pRunningState = NULL; CStoppingState * CContext::pStoppingState = NULL; CContext::CContext( void ) { m_pLiftState = NULL; pOpenningState = new COpenningState(); pCloseingState = new CCloseingState(); pRunningState = new CRunningState(); pStoppingState = new CStoppingState(); } CContext:: ~ CContext( void ) { delete pOpenningState; pOpenningState = NULL; delete pCloseingState; pCloseingState = NULL; delete pRunningState; pRunningState = NULL; delete pStoppingState; pStoppingState = NULL; } CLiftState * CContext::GetLiftState() { return m_pLiftState; } void CContext::SetLiftState(CLiftState * pLiftState) { this -> m_pLiftState = pLiftState; this -> m_pLiftState -> SetContext( this ); } void CContext::Open() { this -> m_pLiftState -> Open(); } void CContext::Close() { this -> m_pLiftState -> Close(); } void CContext::Run() { this -> m_pLiftState -> Run(); } void CContext::Stop() { this -> m_pLiftState -> Stop(); } // State.cpp : 定义控制台应用程序的入口点。 #include " stdafx.h " #include " ILift.h " #include " Lift.h " #include " Context.h " #include " OpenningState.h " #include " CloseingState.h " #include " RunningState.h " #include " StoppingState.h " #include < iostream > using std::cout; using std::endl; void DoIt() { // ILift.h, Lift.h, Lift.cpp ILift * pLift = new CLift(); pLift -> SetState(ILift::STOPPING_STATE); // 电梯的初始条件是停止状态。 pLift -> Open(); // 首先是电梯门开启,人进去 pLift -> Close(); // 然后电梯门关闭 pLift -> Run(); // 再然后,电梯跑起来,向上或者向下 pLift -> Stop(); // 最后到达目的地,电梯停下来 delete pLift; } void DoNew() { // LiftState.h, LiftState.cpp, OpenningState.h, CloseingState.h, RunningState.h, StoppingState.h // Context.h, Context.cpp CContext context; CCloseingState closeingState; context.SetLiftState( & closeingState); context.Close(); context.Open(); context.Run(); context.Stop(); } int _tmain( int argc, _TCHAR * argv[]) { cout << " ----------使用模式之前---------- " << endl; DoIt(); cout << " ----------使用模式之后---------- " << endl; DoNew(); _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF); _CrtDumpMemoryLeaks(); return 0 ; }
状态模式也是行为型模式。