6.模式的组成
环境类(Context):
定义客户感兴趣的接口。维护一个ConcreteState子类的实例,这个实例定义当前状态。
抽象状态类(State):定义一个接口以封装与Context的一个特定状态相关的行为。
具体状态类(ConcreteState):每一子类实现一个与Context的一个状态相关的行为。
7. 实例
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
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
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
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
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
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
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
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;
}