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

来源:互联网 发布:分期购物商城网站源码 编辑:程序博客网 时间:2024/06/15 01:10
 

19.1.解释

概念:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

main(),客户

CLiftState,电梯状态抽象类

CCloseingState,电梯门关闭

COpenningState,电梯门打开

CRunningState,电梯运行

CStoppingState,电梯停止

CContext,电梯的控制面板

说明:CContext保持电梯的状态,并提供操作的接口函数。当函数被调用时,CContext直接调用当前状态的相应函数。由状态的接口函数来确定是否可以执行这个动作,以及修改状态为执行这个动作后的状态。

看代码:第一块是不使用模式的做法,第二块是使用模式的做法,在main()函数里会有调用的方式。

//ILift.h#pragma onceclass 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 onceclass 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;}
复制代码

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

原创粉丝点击