设计模式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状态模式)的更多相关文章
- 设计模式C++学习笔记之十(Builder建造者模式)
建造者模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.一段晦涩难懂的文字,实现创建不同表示的方法就是给创建的过程传入创建的参数.详细的还是看代码吧. 10.1.解释 ...
- 【转】 Pro Android学习笔记(十九):用户界面和控制(7):ListView
目录(?)[-] 点击List的item触发 添加其他控件以及获取item数据 ListView控件以垂直布局方式显示子view.系统的android.app.ListActivity已经实现了一个只 ...
- Android学习笔记(十九)——内容提供器
//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整 ...
- Dynamic CRM 2013学习笔记(十九)自定义审批流1 - 效果演示
CRM的项目,审批流是一个必须品.为了更方便灵活地使用.配置审批流,我们自定义了一整套审批流.首先来看下它的效果: 1. 审批模板 这是一个最简单的审批流,首先指定审批实体,及相关字段,再配置流程节点 ...
- HTML5学习笔记(十九):Lambda和Promise
Lambda 在ES6的标准中称为Arrow Function(箭头函数).下面是一个简单的箭头函数: x => x * x 上面的定义和下面的代码定义效果一样: function (x) { ...
- Java学习笔记(十九)——Java 日志记录 AND log4j
[前面的话] 学习的进度应该稍微在快一点. Java日志到了必须学习怎么使用的时候了,因为在项目中要进行使用.基础性文章,选择性阅读. [结构] java日志对调试,记录运行,问题定位都起到了很重要的 ...
- 设计模式C++学习笔记之十四(Iterator迭代器模式)
14.1.解释 概念:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. main(),客户 IProject,产品接口 CProject,产品类 IIterator,迭代 ...
- 设计模式C++学习笔记之十二(Command命令模式)
命令模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤消的操作.应该是一个比较简单的模式了. 12.1.解释 main(),客户 CIn ...
- C#学习笔记(十九):字典
自定义泛型 泛型类,第一替代符T,第二替代符U using System; using System.Collections.Generic; using System.Linq; using Sys ...
随机推荐
- 二叉树建立及遍历 C++ 源码
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <stdlib.h> using namespace s ...
- JAVA-序列化深拷贝对象
序列化拷贝方法 @SuppressWarnings("unchecked") public static <T extends Serializable> T clon ...
- Hadoop记录-Hadoop集群添加节点和删除节点
1.添加节点 A:新节点中添加账户,设置无密码登陆 B:Name节点中设置到新节点的无密码登陆 C:在Name节点slaves文件中添加新节点 D:在所有节点/etc/hosts文件中增加新节点(所有 ...
- WebStorm记录(1)
开始写前端,使用WebStorm,记录下使用过程 参考 WebStorm 初步使用 & HTML5 学习报告 webstorm怎么运行调试html WebStorm 快速开发教程 --CSS篇 ...
- Sqlcmd使用详解
Sqlcmd实用工具,可以输入 TRANSACT-SQL 语句. 系统过程和脚本文件,通过各种可用模式: 通过命令提示符. 在中查询编辑器在 SQLCMD 模式下. 在 Windows 脚本文件. 在 ...
- bzoj千题计划313:bzoj3879: SvT(后缀数组+st表+单调栈)
https://www.lydsy.com/JudgeOnline/problem.php?id=3879 把所有的后缀取出,按rank排序 求出相邻两个后缀的lcp 每个后缀对答案的贡献就是 与在它 ...
- python+selenium 模拟登陆,自动下单
目前写的实在太粗糙,留着,以后来写上
- 21.Buffer Pool与压缩页/CheckPoint/LSN
一. 思考题解析• 查看Buffer Pool中的Flush List不要在线上操作该SQL语句,开销较大 SELECT pool_id, lru_position, space, page_numb ...
- 基于时间的 SQL注入研究
SQL注入攻击是业界一种非常流行的攻击方式,是由rfp在1998年<Phrack>杂志第54期上的“NT Web Technology Vulnerabilities”文章中首次提出的.时 ...
- solr与tomcat集成
1.准备tomcat8.solr6.solr-home 注意,如果用tomcat7或者之前的版本,因为jar包版本缘故,会出现java.lang.NoSuchMethodError 错误 解压tomc ...