有限状态机:糟糕的设计?

f4.*_*f4. 8 c++ language-agnostic state-machine

有限状态机通常被认为是OOP中的糟糕设计吗?

我听到了很多.并且,在我不得不使用一个非常古老的,没有文档的C++片段之后,我倾向于同意.调试很痛苦.

可读性/可维护性问题呢?

pes*_*669 19

FSM永远不应该被认为是坏的.它们太有用了,但是那些不习惯它们的人会经常认为它们很麻烦.

有许多方法可以用OOP实现一个.有些比其他人更丑.你的低级别人员会使用switch语句,跳转表甚至"转到".

如果您正在寻找一种更简洁的方法,我建议使用Boost的状态图表库,该仅用于在C++中实现UML状态图.它利用现代模板技术,使事物更具可读性.它也表现得很好.

  • +1的描述和Boost链接本身在第一页上包含Robert C. Martin的PDF链接,称为"UML教程:有限状态机".适合任何人进入OO/State Machine的经典之作. (4认同)

SF.*_*SF. 7

有限状态机是实现某种目的的工具.作为任何工具,它们也可能被滥用.

它们并不是最优雅的工具,但是它们擅长的工作几乎不可能通过其他方式实现(通常任何其他方法都注定要比机器差几千倍).

这项工作是在禁止经典等待状态的条件下运作的.

我必须阅读触摸屏.为了读取位置,我必须通过SPI交换大约15个命令.我需要一秒钟好100次读数.我必须在每个命令后等待大约1微秒,因为各个忙碌的旗帜在我继续之前消失.还需要在同一界面上实现许多其他操作,例如设置对比度,更改模式,打开或关闭背光,读取温度.如果我while(BUSY_BIT);为每次等待执行,我会在瞬间吃掉所有CPU.如果我这样做sched_yield()还是usleep(1),我永远不会达到我想要读出的数量.唯一的方法是有限状态机.

但是有一些方法可以使有限状态机也发挥得很好.在幕后隐藏机器并为开发人员提供使用的功能.

到目前为止,我的工作经验主要是基于3种不同的有限状态机的2个系统.

  1. 一个大型门户网站,您可以在每个步骤中从数据库中检索一些数据,并在此基础上准备更多查询.在最后一步中,您将使用数据生成HTML.每个任务 - 一个网页模块 - 都是作为从引擎继承的PHP类实现的.状态保存在类变量中.每个步骤都是一个单独的功能.在步骤结束时,存储的查询被优化并通过缓存发送到引擎,并且答案被提供回原始查询.
  2. 具有许多子系统的嵌入式设备.使用任务泵.每个模块都注册一个从主循环中每秒调用多次的处理程序.处理程序可以使用状态保留静态或类变量中的状态.这种协作式多任务处理允许比在单独的线程中运行所有内存更小的内存占用,允许通过将任务注册两次来手动确定任务的优先级,并使线程以高优先级运行,从而使系统的其余部分蒙上阴影.
  3. 半解释.那个触摸屏.函数调用及其等待状态已注册,但每次只调用一次,然后从程序队列中删除.解释器被称为taskpump的任务,执行有限数量的函数,直到遇到标记为等待状态的函数(或超过要调用的函数的数量).然后它继续,直到等待状态消失.其他任务将作业排队为(有时很长)要执行的函数序列,然后等待结果.通过这种方式,我可以将需要创建的状态数限制为大约4,我需要结果.如果命令是"发送,永不检查结果",如"设置对比度",则它们根本不需要离散状态.因此实际状态是"等待事件并注册请求的数据","等待测量"和"读取结果并正确分配它们".

如果在结构上或顺序编写,代码将简单两倍,清晰三倍.除非它不起作用,否则将与糟糕的表现一起工作.


Pau*_*han 5

无法告诉你他们说什么.

但OO和FSM sorta攻击不同的问题域.在对象正在交互的域中 - 这需要面向对象的方法.在世界处于某种状态的领域 - 需要FSM设计.

实际上,您可以将这些设计与不同的抽象级别混合使用,这将比仅使用其中一个更清晰.