19.1.解释
概念:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
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 ;
}
状态模式也是行为型模式。写了好多天了,才发现如何在页面上插入代码。这样方便多了,看起来也清楚多了。博客园也许需要开个入门贴子,免得新来博客园的童鞋都不大会用。这几天还在学习数据结构中的排序,入排序入手来学习数据结构还是比较容易的。上学的时候只顾着考试了,该学的也都学了,但考完试就全忘掉,已经成为了一种习惯。现在再补回来。鼓励自己加油!一定要做一个学习型的程序员。