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

本文通过电梯控制实例详细解析了状态模式的实现方式与应用场景,展示了如何利用状态模式简化复杂逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

博文很精彩,为方便个人学习特转载,地址:http://www.cnblogs.com/wanggary/archive/2011/04/21/2024117.html
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; }
复制代码

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值