一个简单的电梯状态模型
题目: "简易电梯控制系统"
大家日常生活中经见到的电梯。 你有没有想过它的内部运行机制和实现方法。现在大家就共同讨论一下电梯到底是怎么运行的。
1. 尝试画出你心目中的电梯系统架构图。大胆show出你的想法。
2. 画出电梯运行过程中的状态转换图(停止,上升,下降,开门,报警等),电梯运行的流程图。
====================================================================================================
本文主要是讨论状态机的几种实现方式, 至于电梯的状态划分是否恰当就不管了.
1 前言
本文针对电梯的运行状态转换,描述电梯的状态机模型,提供一种较高效的状态机模式的实现方式。
2 电梯的状态
2.1 状态转换图
2.2 状态列表
由上述状态图,列举状态如下:
停止状态: StateStopping,门是关闭的
电梯上升中: StateGoingUp
电梯下降中: StateGoingDown
电梯开门: StateOpened
超载报警状态:StateWarning,门是开着的
说明:开机即StateStopping状态。电梯停止状态包含关门状态,开门为单独一个状态。
2.3 事件 Event
电梯可接收的事件如下:
上 —— EVENT_UP
下 —— EVENT_DOWN
到达楼层 —— EVENT_STOP
开门 —— EVENT_OPEN
关门 —— EVENT_CLOSE
告警 —— EVENT_WARN
消除告警 —— EVENT_DELWARN
这些事件由硬件根据当前的机械状况产生,比如有人在某层按了按钮,硬件或控制系统会根据实际情况给电梯发上/下事件。电梯状态机负责在当前状态下处理相应事件,以便跳转到下一个新的状态,产生新的运行结果。本文只重点关注电梯本身的状态切换模型。
2.4 状态迁移表
当前状态 |
Event类型 |
转换状态 |
StateStopping |
EVENT_OPEN |
StateOpened |
StateStopping |
EVENT_UP |
StateGoingUp |
StateStopping |
EVENT_DOWN |
StateGoingDown |
StateOpened |
EVENT_CLOSE |
StateStopping |
StateOpened |
EVENT_WARN |
StateWarning |
StateGoingUp |
EVENT_STOP |
StateStopping |
StateGoingDown |
EVENT_STOP |
StateStopping |
StateWarning |
EVENT_DELWARN |
StateOpened |
3 状态机实现
3.1 表驱动方式
描述:略
优点:代码简单,适用于PPP协议等标准的状态机,只需要关心状态表即可。
缺点:状态跳转逻辑由状态表决定,不直观,无法从代码体现状态的转换。
实现:略
3.2 State模式方式
描述:State模式将处理事件的每一个分支,放入一个独立的类中,每一个事件对应派生类的一个虚函数。
优点:每个状态对应一个单独的类,将不同状态的行为分离;通过定义新的派生类,即可增加新的状态和转换。
缺点:一个状态对应一个派生类,增加了子类的数目;状态基类需要定义每个子类的虚函数,即所有状态对象要处理的消息都必须在抽象状态类中申明,增加了冗余;由于所有消息处理函数都是虚拟函数,一方面虚拟函数表占用内存,另一方面增加了调用的间接性。
实现:略。
3.3 成员函数指针实现方式
描述:电梯的当前状态,由一个成员函数指针保存,每个状态对应一个成员函数指针,状态的跃迁形式是成员函数指针的赋值。有事件需要处理时,委托给当前状态处理。
优点:每个状态处理的事件列举清晰,状态转换由成员函数指针赋值实现,成本低。
缺点:代码量与状态数量和事件数量相关,会随之增减。
实现:
/*** 事件.*/
typedef enum tagT_EventType
{EVENT_OPEN = 0,EVENT_UP,EVENT_DOWN,EVENT_CLOSE,EVENT_WARN,EVENT_STOP,EVENT_DELWARN
} T_EventType;
/*** 电梯实体.*/
class Elevator
{
public:typedef void (Elevator::*T_ElevatorState)(T_EventType tEvent); //声明成员函数指针Elevator():m_tNowState(&Elevator::StateStopping) //初始状态停止{}/*** 对外接口, 接收事件*/void ProcessEvent(T_EventType tEvent){(this->*(m_tNowState))(tEvent); //交给当前状态处理, 成员函数调用}private:void StateStopping(T_EventType tEvent); //停止状态void StateOpened(T_EventType tEvent); //开门状态void StateGoingUp(T_EventType tEvent); //上升状态void StateGoingDown(T_EventType tEvent); //下降状态void StateWarning(T_EventType tEvent); //超载状态void SetNextState(T_ElevatorState state){m_tNowState = state; //成员函数指针赋值}T_ElevatorState m_tNowState; /**< 当前状态. */
};void Elevator::StateStopping(T_EventType tEvent)
{switch (tEvent){case EVENT_OPEN://... //通知硬件:开门SetNextState(&Elevator::StateOpened);break;case EVENT_UP://... //通知硬件上升SetNextState(&Elevator::StateGoingUp);break;case EVENT_DOWN://... //通知硬件:下降SetNextState(&Elevator::StateGoingDown);break;default:break;}
}void Elevator::StateOpened(T_EventType tEvent)
{switch (tEvent){case EVENT_CLOSE://... //通知硬件:关门SetNextState(&Elevator::StateStopping);break;case EVENT_WARN://... //通知硬件超载,告警SetNextState(&Elevator::StateWarning);break;default:break;}
}void Elevator::StateGoingUp(T_EventType tEvent)
{switch (tEvent){case EVENT_STOP://... //通知硬件:到达SetNextState(&Elevator::StateStopping);break;default:break;}
}void Elevator::StateGoingDown(T_EventType tEvent)
{switch (tEvent){case EVENT_STOP://... //通知硬件到达SetNextState(&Elevator::StateStopping);break;default:break;}
}void Elevator::StateWarning(T_EventType tEvent)
{switch (tEvent){case EVENT_DELWARN://... //通知硬件删除告警SetNextState(&Elevator::StateOpened);break;default:break;}
}
/*** 控制器, 提供电梯实体和外部系统的接口.*/
class Controller
{
public:void ProcessEvent(T_EventType tEvent){m_tElevator.ProcessEvent(tEvent);}private:Elevator m_tElevator; /**< 电梯实体. */
};
成员函数指针这种实现方式,把对事件的枚举,放在每种状态中;而State模式实现方式,则需要先枚举事件,然后再调用状态机的相应事件响应函数。各有特点。
一个简单的电梯状态模型相关推荐
- 一个简单例子:贫血模型or领域模型
转:一个简单例子:贫血模型or领域模型 贫血模型 我们首先用贫血模型来实现.所谓贫血模型就是模型对象之间存在完整的关联(可能存在多余的关联),但是对象除了get和set方外外几乎就没有其它的方法,整个 ...
- 【Unity3d】 教会你如何做一个简单的电梯系统(升降平台)
博主第一次写博客,语言略俗,有不足之处还请指正! 由于自己还处在unity小白阶段,受2d升降平台的影响(后续我也会上传关于2d升降平台的文章),突发奇想如何用3d做一个电梯系统,查阅网上资料后,发现 ...
- Oracle联立多个表建视图,一个简单的联立方程组模型让你了解内外生变量、如何识别以及2SLS估计步骤...
联立方程模型就是由多个相互联系的单一方程构成的经济计量模型.联立方程模型描述经济变量间的因果关系是双向的,即某一经济变量决定着其它一些经济变量,反过来又受其他经济变量影响.有时由于两个变量之间存在双向 ...
- seq2seq模型_使用Tensorflow搭建一个简单的Seq2Seq翻译模型
1.背景 首先,这篇博文整理自谷歌开源的神经机器翻译项目Neural Machine Translation (seq2seq) Tutorial.如果你直接克隆这个项目按照Tutorial中的说明操 ...
- 深度学习:图像去雨网络实现Pytorch (二)一个简单实用的基准模型(PreNet)实现
本文参考文献:Progressive Image Deraining Networks: A Better and Simpler Baseline Dongwei Ren1, Wangmeng Zu ...
- 通过Dreamweaver建立一个简单的网页音乐盒模型效果/css/h5/
一.结构分析 由图我们可以看到音乐盒的效果右外边框盒子组成,盒子内部又分为两个部分,其中上面部分为标题,下面部分为图片. 二.样式 1.通过外层的大盒子对音乐盒的整体样式进行控制,设置最外层的宽度.高 ...
- 如何用SAP ABAP编程语言实现一个简单的区块链模型
要获取更多Jerry的原创文章,请关注公众号"汪子熙":
- [2013.9.27][cpp]一个简单的链接栈模型
学数据结构的一点想法 LinkStack.h文件: #ifndef LINKSTACH_H #define LINKSTACH_H#include <stdexcept> using st ...
- java 模拟电梯_请使用的Java的多线程知识来编写一个程序,实现一个简单的摩天大楼的电梯模型程序是以一座摩天大楼的多个电梯为背景,用线程、流程控制、随机函数等知识来模拟它。2、电梯的描述:...
请使用的Java的多线程知识来编写一个程序,实现一个简单的摩天大楼的电梯模型 程序是以一座摩天大楼的多个电梯为背景,用线程.流程控制.随机函数等知识来模拟它. 2. 电梯的描述: 电梯是日常生活中经常 ...
最新文章
- 【顶会资源汇总】2020最新视觉描述生成文献大列表
- 使用js实现微信小页面翻页的原理介绍
- Java程序员周末时间搞锭银行信息管理系统毕业设计(java+springboot+mybatis+mysql+vue+elementui)等实现
- 内核使用硬件ip的dma,dma_alloc_coherent 与 dma_alloc_writecombine (转)
- 面向机器学习的特征工程 三、文本数据: 展开、过滤和分块
- java dom4j读写xml_Java:简单的读写XML文件之使用DOM4J读写
- What is Closure
- android 线程使用监控思路分享
- 牛腩新闻发布系统—发布网站
- 如何从零开始搭建SRE?
- 4月计算机领域的国际会议,计算机领域国际会议分区表
- android中adb是什么意思,adb是什么意思?安卓系统常用adb命令怎么用?
- 华为云安装:宝塔linux+wordpress建站
- 冲向2021 荣耀“无限”创新
- nginx 会话保持
- Winbond W25Q128JVSIQ 串行闪存
- 线程函数参数(LPVOID Param)
- 域名 超过注册日两年_域名到期之后一般可以保留多久?
- java毕业设计维保管理系统mybatis+源码+调试部署+系统+数据库+lw
- 好用的电脑数据恢复软件推荐
热门文章
- 百度AI达人创造营|第一课、拍案叫绝的创意
- 锁相环原理(PLL)
- 位移模块\A6210\TSI\CSI6500\EPRO
- 对给定平面任意两点坐标(x1,y1)和(x2,y2),求这两点之间的距离
- 在word里,毕业论文和开题报告的参考文献目录如何设置成第二行空两格的格式?(介绍两种方法)
- 医疗汇报医学演示PPT模板
- Unity开发4 资源、商店、地形的绘制
- 技术选型-RabbitMQ 和 Kafka
- 最全的ORACLE-SQL笔记(转,出处不详)
- 使用python连接mysql和发送post请求