一个简单的电梯状态模型
来源:互联网 发布:计算机系统监控软件 编辑:程序博客网 时间:2024/05/01 01:25
题目: "简易电梯控制系统"
大家日常生活中经见到的电梯。 你有没有想过它的内部运行机制和实现方法。现在大家就共同讨论一下电梯到底是怎么运行的。
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模式实现方式,则需要先枚举事件,然后再调用状态机的相应事件响应函数。各有特点。
- 一个简单的电梯状态模型
- 一个简单的对象模型
- 一个简单的对象模型
- nyoj 1070 诡异的电梯 简单dp
- 一个电梯运行的模拟实现
- 一个简单的wifi状态提示广播
- java 多线程 模拟一台电梯的工作状态
- OC一个简单的模型的创建
- 一个简单的线程池设计模型
- 一个简单的回调函数模型
- 一个简单的库存控制模型
- 快速实现一个简单的bigpipe模型
- 一个简单的双缓冲通讯模型
- TCP/IP模型的一个简单解释
- TCP/IP模型的一个简单解释
- TCP/IP模型的一个简单解释
- 一个简单的审批流程模型
- TCP/IP模型的一个简单解释
- AG阅读总结10.2——数据文件管理
- Firefox Add-ons
- C#中的格式化输出
- Android ViewGroup提高绘制性能
- 中兴U880安装驱动
- 一个简单的电梯状态模型
- JSP内置对象(9个常用的内置对象)
- 平衡树构造算法
- 从HWND获取IE的IWebBrowser2接口的函数
- 【Android Training - Performance】优化电池续航能力[Lesson 4 - 按需操控Broadcast Receivers是否开启]
- 【斜率优化】特别行动队
- <<打工是最愚蠢的投资》 ——李嘉诚在大梅沙的演讲
- 不论你学什么专业,都应该了解这些
- getopt函数的使用