码迷,mamicode.com
首页 > 其他好文 > 详细

有限状态机与状态模式

时间:2015-10-22 23:48:07      阅读:306      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

状态机

   

       在理解状态机之前,总是把状态里简单地理解为状态模式,最近,我仔细分析了状态机的实现机制,发现状态机和状态模式还是有很大的不同。

       一,状态模式是具体的,针对每个需求有一个状态集,并为其实现特有的迁移机制。状态机是抽象的,不是针对特定的需求,而是对各种与相关的问题的进一步抽象,那么用状态机回头去实现状态模式的时候,只需要关注问题本身,而不用去关心如何实现,也就是说你只需要绘制出状态迁移图,状态机就能帮你去实现。

       二,状态模式的是命令式的,我们必须一步一步地去实现状态之间如何迁移,以及迁移过程中需要做一些额外的事情。状态机是声明式的,使用状态机,你只需要声明状态及状态的迁移路线,而不需要去提供执行层面的命令,状态机自动帮你去做。

       三,状态模式容易理解,状态机确实不是那么容易理解,估计很多人会想我一样,认为其没有什么差别,这是不对的。(这也算是一个区别,哈哈)

       区分了这么多,言归正传,来分析一下一个典型的状态机的实现,首先简要看一下类图:

技术分享

       一,Event,顾名思义是事件的意思,在状态迁移过程中所发生的事情,分为主动事件ActiveEvent(对应原著里的Command),被动事件PassiveEvent。

       主动事件是进入某个状态以后自动往状态机以外发送信息的事件,被动事件是被状态机接受处理完成状态迁移的事件。

       二,CommandChannel,命令通道用来接收被动事件和发送主动事件,被控制器所持有,特定的需求可以实现各自具体的命令通道。

       三,State,状态和状态模式里的每个具体状态对应,区别是状态模式里的每个状态对应一个特定的状态类(命令式,有效的信息有类名,迁移方法),而这里的State是一个简单的结构,主要包括名称,迁移表(对应前者的类名和迁移方法),主动事件表(进入该状态以后自动调用),自动激发事件表,在主动事件调用完毕以后,主动状态机本身发送被动事件,用途是有的状态只是一个中间临时状态,会被自动迁移到下一个状态,比如一扇门而言:Open事件导致门进入Opening(正在打开)状态,这个状态会做一个动作(角度慢慢扩大),然后自动迁移到Opened(已经打开)状态,那么Opening就会拥有一个Open的自动激发事件,在其处理的结尾将这个事件发送到状态机以自动切换到Opened状态

       三,Transition,状态切换路径,包含EventCode(事件源,指定了当前状态下对该事件感兴趣),Source(源状态),Trigger(触发器),Target(目的状态)。

       四,StateMachine,到状态机了,状态机本身很简单,包含Start(状态机的起始状态),AllStates(该状态机的所有可能的状态)。

       五,Controller,控制器负责接收外部事件Handle(eventcode),指导状态机完成窗台迁移,包括CurrentState(状态机内部的当前状态),Machine(状态机),CommandChannel(命令通道)。

       以上介绍了简单的类图,值得提醒的一点就是,从静态结构看,唯一可以扩展的地点就是CommandChannel,这个类有一个DoSend方法需要实现,每个具体的应用实现这个方法来根据其状态参数做具体的操作。

       下面从源代码的角度来观察:

       一,抽象事件

技术分享

   

       二,主动事件

技术分享

       三,被动事件

技术分享

       四,       状态

技术分享

技术分享

   

       五,状态机

技术分享

技术分享

       六,迁移

技术分享

七,控制器

技术分享

技术分享

以上是详细的代码,有兴趣看完的话,我也是醉了(同道中人啊)。下面我做两个简单的例子介绍,都是关于门的例子第一个例子如下:技术分享有两个状态:开和关,在开的状态下接受到Close事件,则迁移到关状态,在关状态下,接受到Open事件,则迁移到开状态。测试如下:

技术分享

代码是不是"声明式"味道的啊:)。

第二个例子在这个例子上增加两个状态:正在关闭,正在打开,如下:

技术分享

测试代码如下:

技术分享

技术分享

参考书目《领域特定语言》

有限状态机与状态模式

标签:

原文地址:http://www.cnblogs.com/stst/p/4903041.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!