- 浏览: 370093 次
- 性别:
- 来自: 苏州
文章分类
- 全部博客 (335)
- C++ (190)
- 设计模式 (43)
- 数据库技术 (5)
- 网络编程 (11)
- 自动化测试 (6)
- Linux (13)
- OpenSSL (10)
- MS Crypt API (5)
- SCM (2)
- English (4)
- Android (10)
- EMV规范 (1)
- Saturn Platform (0)
- C (10)
- SQL (2)
- ASP.NET (3)
- 英语口语学习 (3)
- 调试工具 (21)
- 编译技术 (5)
- UML (1)
- 项目管理 (5)
- 敏捷开发 (2)
- Http Server (6)
- 代码审查、代码分析 (5)
- 面试基础 (10)
- 重点知识 (16)
- STL (6)
- Efficient C++资料 (8)
- 数据结构和算法 (7)
- 读书笔记 (0)
- 开源项目 (4)
- 多线程 (2)
- Console App (6)
- 个人开源项目 (4)
- IBM DevelopWorks (4)
- Java (16)
- 内存泄漏相关调试和检测 (13)
- 软件测试相关技术 (2)
- C# (11)
- Apple Related (1)
- 软件测试和管理 (2)
- EMV (1)
- Python (1)
- Node.js (6)
- JavaScript (5)
- VUE (1)
- Frontend (1)
- Backend (4)
- RESTful API (3)
- Firebase (3)
最新评论
-
u013189503:
来个密码吧
[C++][Logging] 项目中写日志模块的实现 -
wyf_vc:
来个密码啊!!
[C++][Logging] 项目中写日志模块的实现
问题
每个人、事物在不同的状态下会有不同表现(动作),而一个状态又会在不同的表现下转移到下一个不同的状态(State)。最简单的一个生活中的例子就是:地铁入口处,如果你放入正确的地铁票,门就会打开让你通过。在出口处也是验票,如果正确你就可以ok,否则就不让你通过(如果你动作野蛮,或许会有报警(Alarm),:))。
有限状态自动机(FSM)也是一个典型的状态不同,对输入有不同的响应(状态转移)。通常我们在实现这类系统会使用到很多的Switch/Case语句,Case某种状态,发生什么动作,Case另外一种状态,则发生另外一种状态。但是这种实现方式至少有以下两个问题:
1)当状态数目不是很多的时候,Switch/Case可能可以搞定。但是当状态数目很多的时候(实际系统中也正是如此),维护一大组的Switch/Case语句将是一件异常困难并且容易出错的事情。
2)状态逻辑和动作实现没有分离。在很多的系统实现中,动作的实现代码直接写在状态的逻辑当中。这带来的后果就是系统的扩展性和维护得不到保证。
模式选择
State模式就是被用来解决上面列出的两个问题的,在State模式中我们将状态逻辑和动作实现进行分离。当一个操作中要维护大量的case分支语句,并且这些分支依赖于对象的状态。State模式将每一个分支都封装到独立的类中。
实现
请看附件 state.zip
PS:也可以参考blaze中的代码 loginstatemachine.cpp
纯虚函数的测试
在写测试代码的时候,偶然发现在父类确定纯虚函数的时候居然也可以有一个实现体,很奇怪!!!于是也写了代码测试了一下,总结出规律如下(不一定完全正确,完全是个人理解)
1)父类在定义纯虚函数的时候,可以有实现体,但是没有任何意义,因为父类不能实例化,这段代码永远不会被调用到;
2)子类在继承父类的时候,可以不实现纯虚函数体;但是前提是,这个子类不会被实例化
3)子类在继承父类的时候,如果需要实例化,就必须实现纯虚函数,不然虚表中对应函数的地址就无法确定,编译出错。
4)测试代码请见PureVirtualTest.zip
下面的部分请看以下链接http://blog.csdn.net/hguisu/article/details/7557252
每个人、事物在不同的状态下会有不同表现(动作),而一个状态又会在不同的表现下转移到下一个不同的状态(State)。最简单的一个生活中的例子就是:地铁入口处,如果你放入正确的地铁票,门就会打开让你通过。在出口处也是验票,如果正确你就可以ok,否则就不让你通过(如果你动作野蛮,或许会有报警(Alarm),:))。
有限状态自动机(FSM)也是一个典型的状态不同,对输入有不同的响应(状态转移)。通常我们在实现这类系统会使用到很多的Switch/Case语句,Case某种状态,发生什么动作,Case另外一种状态,则发生另外一种状态。但是这种实现方式至少有以下两个问题:
1)当状态数目不是很多的时候,Switch/Case可能可以搞定。但是当状态数目很多的时候(实际系统中也正是如此),维护一大组的Switch/Case语句将是一件异常困难并且容易出错的事情。
2)状态逻辑和动作实现没有分离。在很多的系统实现中,动作的实现代码直接写在状态的逻辑当中。这带来的后果就是系统的扩展性和维护得不到保证。
模式选择
State模式就是被用来解决上面列出的两个问题的,在State模式中我们将状态逻辑和动作实现进行分离。当一个操作中要维护大量的case分支语句,并且这些分支依赖于对象的状态。State模式将每一个分支都封装到独立的类中。
实现
请看附件 state.zip
PS:也可以参考blaze中的代码 loginstatemachine.cpp
纯虚函数的测试
在写测试代码的时候,偶然发现在父类确定纯虚函数的时候居然也可以有一个实现体,很奇怪!!!于是也写了代码测试了一下,总结出规律如下(不一定完全正确,完全是个人理解)
1)父类在定义纯虚函数的时候,可以有实现体,但是没有任何意义,因为父类不能实例化,这段代码永远不会被调用到;
2)子类在继承父类的时候,可以不实现纯虚函数体;但是前提是,这个子类不会被实例化
3)子类在继承父类的时候,如果需要实例化,就必须实现纯虚函数,不然虚表中对应函数的地址就无法确定,编译出错。
4)测试代码请见PureVirtualTest.zip
下面的部分请看以下链接http://blog.csdn.net/hguisu/article/details/7557252
#ifndef NORMAL_H #define NORMAL_H typedef enum Em_Algorithm_TYPE { AlgorithmType_SHA1 = 1, AlgorithmType_SHA256 = 2 }ALGORITHM_TYPE, *PALGORITHM_TYPE; typedef enum Em_Lift_Type { //电梯的四个状态 OPENING_STATE = 1, //门敞状态 CLOSING_STATE = 2, //门闭状态 RUNNING_STATE = 3, //运行状态 STOPPING_STATE = 4 //停止状态; }LIFT_TYPE; class ILift { public: ILift(); virtual ~ILift(); //设置电梯的状态 virtual void setState(LIFT_TYPE emStateType) = 0; //首先电梯门开启动作 virtual void open() = 0; //电梯门有开启,那当然也就有关闭了 virtual void close() = 0; //电梯要能上能下,跑起来 virtual void run() = 0; //电梯还要能停下来,停不下来那就扯淡了 virtual void stop() = 0; }; class Lift : public ILift { public: Lift(); virtual ~Lift(); virtual void setState(LIFT_TYPE emStateType); //电梯门关闭 virtual void close(); //电梯门开启 virtual void open(); ///电梯开始跑起来 virtual void run(); //电梯停止 virtual void stop(); private: LIFT_TYPE m_LiftYype; }; void Lift_Run(); #endif //NORMAL_H
#include "Normal.h" #include <iostream> using namespace std; ////////////////////////////////////////////////////////////////////////// ILift::ILift() { } ILift::~ILift() { } ////////////////////////////////////////////////////////////////////////// Lift::Lift() { } Lift::~Lift() { } void Lift::setState(LIFT_TYPE emStateType) { this->m_LiftYype = emStateType; } //电梯门关闭 void Lift::close() { //电梯在什么状态下才能关闭 switch(this->m_LiftYype) { case OPENING_STATE: //如果是则可以关门,同时修改电梯状态 { this->setState(CLOSING_STATE); cout << "OPENING_STATE ==> CLOSING_STATE" << endl; break; } case CLOSING_STATE: //如果电梯就是关门状态,则什么都不做 { //do nothing; cout << "CLOSING_STATE" << endl; break; } case RUNNING_STATE: //如果是正在运行,门本来就是关闭的,也说明都不做 { //do nothing; cout << "RUNNING_STATE" << endl; break; } case STOPPING_STATE: //如果是停止状态,本也是关闭的,什么也不做 { //do nothing; cout << "RUNNING_STATE" << endl; break; } } } //电梯门开启 void Lift::open() { //电梯在什么状态才能开启 switch(this->m_LiftYype) { case OPENING_STATE: //如果已经在门敞状态,则什么都不做 { //do nothing; cout << "OPENING_STATE" << endl; break; } case CLOSING_STATE: //如是电梯时关闭状态,则可以开启 { this->setState(OPENING_STATE); cout << "CLOSING_STATE ==> OPENING_STATE" << endl; break; } case RUNNING_STATE: //正在运行状态,则不能开门,什么都不做 { //do nothing; cout << "RUNNING_STATE" << endl; break; } case STOPPING_STATE: //停止状态,淡然要开门了 { this->setState(OPENING_STATE); cout << "STOPPING_STATE ==> OPENING_STATE" << endl; break; } } } ///电梯开始跑起来 void Lift::run() { switch(this->m_LiftYype) { case OPENING_STATE: //如果已经在门敞状态,则不你能运行,什么都不做 { //do nothing; cout << "OPENING_STATE" << endl; break; } case CLOSING_STATE: //如是电梯时关闭状态,则可以运行 { this->setState(RUNNING_STATE); cout << "CLOSING_STATE ==> RUNNING_STATE" << endl; break; } case RUNNING_STATE: //正在运行状态,则什么都不做 { //do nothing; cout << "RUNNING_STATE" << endl; break; } case STOPPING_STATE: //停止状态,可以运行 { this->setState(RUNNING_STATE); cout << "STOPPING_STATE ==> RUNNING_STATE" << endl; break; } } } //电梯停止 void Lift::stop() { switch(this->m_LiftYype) { case OPENING_STATE: //如果已经在门敞状态,那肯定要先停下来的,什么都不做 { //do nothing; cout << "OPENING_STATE" << endl; break; } case CLOSING_STATE: //如是电梯时关闭状态,则当然可以停止了 { this->setState(CLOSING_STATE); cout << "CLOSING_STATE ==> CLOSING_STATE" << endl; break; } case RUNNING_STATE: //正在运行状态,有运行当然那也就有停止了 { this->setState(CLOSING_STATE); cout << "RUNNING_STATE ==> CLOSING_STATE" << endl; break; } case STOPPING_STATE: //停止状态,什么都不做 { //do nothing; cout << "STOPPING_STATE" << endl; break; } } } ////////////////////////////////////////////////////////////////////////// void Lift_Run() { Lift* pList = new Lift(); //电梯的初始条件应该是停止状态 pList->setState(STOPPING_STATE); //首先是电梯门开启,人进去 pList->open(); //然后电梯门关闭 pList->close(); //再然后,电梯跑起来,向上或者向下 pList->run(); //最后到达目的地,电梯挺下来 pList->stop(); }
#ifndef STATE_H #define STATE_H #include <Windows.h> class Context; class LiftState { public: LiftState(); virtual ~LiftState(); void setContext(Context* pContext); //首先电梯门开启动作 virtual void open() = 0; //电梯门有开启,那当然也就有关闭了 virtual void close() = 0; //电梯要能上能下,跑起来 virtual void run() = 0; //电梯还要能停下来,停不下来那就扯淡了 virtual void stop() = 0; protected: //定义一个环境角色,也就是封装状态的变换引起的功能变化 Context* m_pContext; }; class OpenningState; class CloseingState; class RunningState; class StoppingState; class Context { public: Context(); virtual ~Context(); LiftState* getLiftState(); void setLiftState(LiftState* pLiftState); void open(); void close(); void run(); void stop(); private: //定一个当前电梯状态 LiftState* m_pLiftState; public: //定义出所有的电梯状态 OpenningState* m_pOpenningState; CloseingState* m_pCloseingState; RunningState* m_pRunningState; StoppingState* m_pStoppingState; }; class OpenningState : public LiftState { public: OpenningState(); virtual ~OpenningState(); virtual void close(); virtual void open(); virtual void run(); virtual void stop(); }; class CloseingState : public LiftState { public: CloseingState(); virtual ~CloseingState(); virtual void close(); virtual void open(); virtual void run(); virtual void stop(); }; class RunningState : public LiftState { public: RunningState(); virtual ~RunningState(); virtual void close(); virtual void open(); virtual void run(); virtual void stop(); }; class StoppingState : public LiftState { public: StoppingState(); virtual ~StoppingState(); virtual void close(); virtual void open(); virtual void run(); virtual void stop(); }; void State_Run(); #endif STATE_H
#include "State.h" ////////////////////////////////////////////////////////////////////////// LiftState::LiftState() { m_pContext = NULL; } LiftState::~LiftState() { } void LiftState::setContext(Context* pContext) { this->m_pContext =pContext; } ////////////////////////////////////////////////////////////////////////// Context::Context() { m_pLiftState = NULL; m_pOpenningState = new OpenningState(); m_pCloseingState = new CloseingState(); m_pRunningState = new RunningState(); m_pStoppingState = new StoppingState(); } Context::~Context() { } LiftState* Context::getLiftState() { return this->m_pLiftState; } void Context::setLiftState(LiftState* pLiftState) { this->m_pLiftState = pLiftState; //把当前的环境通知到各个实现类中 this->m_pLiftState->setContext(this); } void Context::open() { this->m_pLiftState->open(); } void Context::close() { this->m_pLiftState->close(); } void Context::run() { this->m_pLiftState->run(); } void Context::stop() { this->m_pLiftState->stop(); } ////////////////////////////////////////////////////////////////////////// OpenningState::OpenningState() { } OpenningState::~OpenningState() { } void OpenningState::close() { //状态修改 this->m_pContext->setLiftState(this->m_pContext->m_pColseingState); //动作委托为CloseState来执行 this->m_pContext->getLiftState()->close(); } //打开电梯门 void OpenningState::open() { //echo 'lift open...', '<br/>'; } //门开着电梯就想跑,这电梯,吓死你! void OpenningState::run() { //do nothing; } //开门还不停止? void OpenningState::stop() { //do nothing; } ////////////////////////////////////////////////////////////////////////// CloseingState::CloseingState() { } CloseingState::~CloseingState() { } //电梯门关闭,这是关闭状态要实现的动作 void CloseingState::close() { //echo 'lift close...', '<br/>'; } //电梯门关了再打开,逗你玩呢,那这个允许呀 void CloseingState::open() { this->m_pContext->setLiftState(this->m_pContext->m_pOpenningState); //置为门敞状态 this->m_pContext->getLiftState()->open(); } //电梯门关了就跑,这是再正常不过了 void CloseingState::run() { this->m_pContext->setLiftState(this->m_pContext->m_pRunningState); //设置为运行状态 this->m_pContext->getLiftState()->run(); } //电梯门关着,我就不按楼层 void CloseingState::stop() { this->m_pContext->setLiftState(this->m_pContext->m_pStoppingState); //设置为停止状态 this->m_pContext->getLiftState()->stop(); } ////////////////////////////////////////////////////////////////////////// RunningState::RunningState() { } RunningState::~RunningState() { } //电梯门关闭?这是肯定了 void RunningState::close() { //do nothing } //运行的时候开电梯门?你疯了!电梯不会给你开的 void RunningState::open() { //do nothing } //这是在运行状态下要实现的方法 void RunningState::run() { //echo 'lift run...', '<br/>'; } //这个事绝对是合理的,光运行不停止还有谁敢做这个电梯?!估计只有上帝了 void RunningState::stop() { this->m_pContext->setLiftState(this->m_pContext->m_pStoppingState); //环境设置为停止状态; this->m_pContext->getLiftState()->stop(); } ////////////////////////////////////////////////////////////////////////// StoppingState::StoppingState() { } StoppingState::~StoppingState() { } //停止状态关门?电梯门本来就是关着的! void StoppingState::close() { //do nothing; } //停止状态,开门,那是要的! void StoppingState::open() { this->m_pContext->setLiftState(this->m_pContext->m_pOpenningState); this->m_pContext->getLiftState()->open(); } //停止状态再跑起来,正常的很 void StoppingState::run() { this->m_pContext->setLiftState(this->m_pContext->m_pRunningState); this->m_pContext->getLiftState()->run(); } //停止状态是怎么发生的呢?当然是停止方法执行了 void StoppingState::stop() { //echo 'lift stop...', '<br/>'; } ////////////////////////////////////////////////////////////////////////// void State_Run() { Context* pContext = new Context(); pContext->setLiftState(new CloseingState()); pContext->open(); pContext->close(); pContext->run(); pContext->stop(); }
#include "Normal.h" #include "State.h" #include <iostream> using namespace std; int main(int argc, char *argv[]) { ////////////////////////////////////////////////////////////////////////// Lift_Run(); State_Run(); return 0; }
- State.zip (5 KB)
- 下载次数: 3
- PureVirtualTest.zip (3.9 KB)
- 下载次数: 1
- loginstatemachine.zip (11.3 KB)
- 下载次数: 1
- State_For_Lift.zip (6.3 KB)
- 下载次数: 0
发表评论
-
FreeRTOS
2022-03-05 16:31 248Ref https://blog.csdn.net/weix ... -
串口通讯相关
2018-11-02 13:44 411https://bbs.csdn.net/wap/topics ... -
[转]C++验证IP是否可以PING通
2018-10-30 17:54 1328https://www.cnblogs.com/guoyz13 ... -
C++/MFC 換皮膚
2018-10-20 11:05 477https://blog.csdn.net/u01123991 ... -
WinCE 截屏 - C++ 代碼
2018-08-31 09:45 574// this function create a bmp ... -
Android NDK搭建環境
2017-11-27 13:25 582https://www.cnblogs.com/ut2016- ... -
8583协议相关
2017-10-17 13:38 5738583相关资料,整理中... -
Java高级应用之JNI
2017-06-19 09:00 600参考link http://www.cnblogs.com/l ... -
C++实现ping功能
2017-04-18 11:21 2155基础知识 ping的过程是向目的IP发送一个type=8的I ... -
OpenSSL 编译环境搭建
2017-03-27 15:01 9061 安裝VS2008到 c:\Program Files (x ... -
最优非对称加密填充(OAEP)
2017-03-25 14:53 1582OpenSSL命令---rsautl http://blog. ... -
[Platform Builder] 设置SVM OS build Env
2016-11-10 11:39 01 copy one OSDesign Project to ... -
[Windows] System Error Codes(GetLastError )0-----5999
2016-10-26 13:28 1881ERROR_SUCCESS 0 (0x0) T ... -
开源Windows驱动程序框架
2016-09-17 21:35 871转自 http://code.csdn.net/news/28 ... -
c/c++代码中执行cmd命令
2016-09-14 14:50 1908转自 http://blog.csdn.net/slixinx ... -
C#使用C++标准DLL实例(包含callback)
2016-09-11 19:44 1086C++编写标准Win32DLL如下 头文件 /***** ... -
C#调用C++的DLL搜集整理的所有数据类型转换方式
2016-09-09 16:07 969转自 http://www.cnblogs.com/zeroo ... -
WinCE CPU使用率计算 测试工具
2016-09-08 16:14 991转自 http://blog.csdn.net/jan ... -
switch在C++与C#中的一些差异
2016-09-08 15:19 810参考链接 http://blog.csdn.net/weiwe ... -
C++ 鼠标模拟程序
2016-09-04 12:09 1612转自 http://blog.csdn.net/weixinh ...
相关推荐
State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif else 进行状态切换, 如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了. 不只是根据状态,也有根据属性.如果...
状态模式是一种行为设计模式,它允许对象在内部状态改变时改变其行为,对象看起来似乎修改了它的类。在C#编程中,这种模式被广泛应用于处理具有多种状态的对象,使得对象的状态转换更加清晰和易于管理。 状态模式的...
这是JAVA设计模式中属于行为模式的部分,包括Template(模板模式)、Chain of Responsibility(责任链模式)、Memento(纪念品模式)、Mediator(中介模式)、Strategy(策略模式)、State 、Observer(观察者模式)、Visitor...
在这个“设计模式_行为模式”主题中,我们将深入探讨几种关键的行为模式。 1. 责任链模式(Chain of Responsibility):此模式允许创建一个处理请求的对象链,每个对象都可以处理请求或将其传递给链中的下一个对象...
### 状态模式(State Pattern) #### 概念与定义 状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为,使对象看起来像是修改了它的类。该模式通过引入一个代表各种状态的类以及一个行为随着这些...
在博文《Android的状态机模式StateMachine与State》中,作者可能会详细介绍如何创建和使用这两种组件。通常,状态机的实现会涉及到以下步骤: 1. **定义状态接口或抽象类**:创建一个State接口或抽象类,其中包含...
状态模式(State Pattern)是一种行为设计模式,它允许对象在内部状态改变时改变其行为,对象看起来似乎修改了它的类。这种模式将一个对象的行为分解为各个独立的状态,并且每个状态都封装在自己的类中,使得对象在...
State模式是一种行为型设计模式,用于在不改变对象自身的情况下改变其行为。它的核心思想是:通过引入一系列的具体状态类来表示对象的不同状态,并将这些状态封装为独立的类,从而使对象能够在这些状态之间自由切换...
状态模式通常包含三个主要角色:Context(上下文)、State(抽象状态)和ConcreteState(具体状态)。 上下文是拥有状态的对象,它定义了与该状态相关的接口,并负责在适当的时候将请求委托给相应的状态对象处理。...
状态模式是一种行为设计模式,它使你能在运行时改变对象的行为。在状态模式中,一个对象的状态变化会导致其行为的变化,这种变化不是通过改变对象的类来实现的,而是通过改变对象的状态。这个模式的核心是封装可能...
本篇将重点讨论C#中的行为模式,特别是备忘录模式。 备忘录模式是一种行为设计模式,它在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将对象恢复到原先保存的状态。...
State模式是一种行为模式,旨在解决允许一个对象在其内部状态改变时改变它的行为的问题。该模式可以允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。 Strategy模式 Strategy模式是一种...
状态模式是一种行为设计模式,它允许对象在内部状态改变时改变其行为,对象看起来似乎修改了它的类。这种模式常用于处理对象的状态变化,并且使代码结构清晰,易于维护。 在C++中,状态模式通常包含以下几个关键...
本篇将探讨两种重要的行为设计模式:责任链模式(Chain of Responsibility Pattern)和状态模式(State Pattern)。 **责任链模式**是一种使多个对象都有机会处理请求的模式,避免请求发送者与接收者之间的耦合。在...
State模式是一种行为设计模式,它允许对象在内部状态改变时改变其行为,看起来像是改变了它的类。这种模式常被用于处理具有多种状态的对象,使得对象的状态转换更加清晰,代码更易于理解和维护。 在State模式中,...
"State模式"是一种行为设计模式,它允许对象在内部状态改变时改变其行为,看起来好像对象改变了它的类。这种模式通常用于处理对象的状态变化,使得代码更易于理解和维护。在软件工程中,当一个对象的行为取决于它的...