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

摘要:
对象似乎已修改其类。Main(),客户CLiftState,电梯状态抽象类CCloseingState,电梯门关闭COpeningState,电梯开门CRunningState,电梯运行CStopingState,升降机停止CContext,电梯控制面板描述:CContext保持电梯状态并提供操作界面功能。状态的接口函数确定动作是否可以执行,并将状态更改为动作执行后的状态。

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状态模式)第1张

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

免责声明:文章转载自《设计模式C++学习笔记之十九(State状态模式)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Android jdb debugwebstorm添加vue插件支持下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

玩客云安装Armbian

首先,轻扫uboot。阿里云的网卡非常痛苦。如果您没有滑动特定的uboot,则无法驱动它。有三个命令可以滑动uboot,可以按顺序执行:usbstart;fatloadusb01200000u引导。binstorerom_write12000000060000 saveenv三个命令执行后,关闭并重新启动Play Keyun一次,然后再次进入中断模式。再次插...

plsql 导出查询结果

单击青色按钮,表示所查询的所有数据都将导出到指定文件,而不仅仅是以下列表中显示的数据行;无需单击“获取最后一页”按钮。注意:选择导出到excel文件时,需要注意默认导出为*。xlsx格式。您可以选择*。xls格式,但*。xls格式只能容纳65536行数据。如果要导出的数据超过最大值,则必须更改为*。xlsx格式!如果您仍然使用此格式,后面的数据将覆盖以前的数...

搭建我的世界服务器(史上最详细) java环境配置 ,免费内网穿透,家庭用电脑也欧克

服务器部署周末想要和好基友联机?这里有最简单的开服教程!最后打开我的世界输入服务器ip,和你自己在内网穿透网站设置的端口连接即可成功要想服务器稳定运行,要保证命令窗口和端口映射一直开着...

ActiveMQ教程(消息发送和接受)

activemq全部&lt;版本&gt;{版本}&lt;/版本&gt;名称为ActiveMqUtilitimportjava。util。日期importorg.apache.activemq.activemq连接//创建链接Connectionconnection=null;61616");...

动态表单

在完成数据表元数据的维护后,关键点是生成表单。表单生成主要基于上表,该表记录了类型、长度、字段是否可以为空、界面显示方法以及表单何时生成等一系列信息。用这个生成表单并不难,嗯,有句话说得好,“困难的事情必须容易完成”。最后,最困难的事情是由一些简单的问题组成的。由于现在使用了struts 2,因此需要对接口进行一系列判断,代码如下:˂s:iftest='#f...

vue页面出现乱码,那么就需要在当前页面设置编码为utf-8

如果HTML在中文中出现乱码,则将其修改如下:必须将其设置为zh-CN简体中文。如果设置为lang=“en”,则表示英语,如果内容是中文,则可能会出现乱码或者它可以缩写为:或请记住,元中只有两个属性。两个值:http equiv=“Content-Type”Content=“text/html;charset=utf-8”//值中有一个分号。中国常用代码:u...