设计模式C++学习笔记之十九(State状态模式)

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 ;
}

《设计模式C++学习笔记之十九(State状态模式)》

状态模式也是行为型模式。写了好多天了,才发现如何在页面上插入代码。这样方便多了,看起来也清楚多了。博客园也许需要开个入门贴子,免得新来博客园的童鞋都不大会用。这几天还在学习数据结构中的排序,入排序入手来学习数据结构还是比较容易的。上学的时候只顾着考试了,该学的也都学了,但考完试就全忘掉,已经成为了一种习惯。现在再补回来。鼓励自己加油!一定要做一个学习型的程序员。

    原文作者:设计模式
    原文地址: http://www.cnblogs.com/wanggary/archive/2011/04/21/2024117.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞