有限状态机与状态模式

状态机

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

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

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

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

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

一,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事件,则迁移到开状态。测试如下:

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

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

测试代码如下:

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

时间: 2024-10-12 14:07:24

有限状态机与状态模式的相关文章

Atitit. 有限状态机 fsm 状态模式

Atitit. 有限状态机 fsm 状态模式 1. 有限状态机 1 2. "状态表"和"状态轮换表" 1 3. 有限状态机概念(状态(State)事件(Event)转换(Transition) 动作(Action) 2 4. 状态机的应用场景 2 4.1. ,"有限状态机"在游戏的人工智能方面是很有用处的. 2 4.2. 用状态机模式消除复杂的 if else 逻辑 2 4.3. 源码文本处理状态机 2 4.4. 正则表达式(regexp),判断

【游戏设计模式】之三 状态模式、有限状态机 & Unity版本实现

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/52824776 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 游戏开发过程中,各种游戏状态的切换无处不在.但很多时候,简单粗暴的if else加标志位的方式并不能很地道地解决状态复杂变换的问题,这时,就可以运用到状态模式以及状态机来高效地完成任务.状态模式与状态机,因为他们关联紧密,常

策略模式的孪生兄弟——对状态模式的深度复习总结

俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的总结知识点如下: 和策略模式的比较 状态模式概念和例子 应用场景 责任链模式和状态模式对比 一种代码优化的思路 java.util.Iterator里也有状态模式的影子 状态模式的优缺点 有限状态机及其应用 前面有总结——策略模式,之前早就觉得策略和状态设计模式有一些相似…… 接口的常用用法都有什么?策略设计模式复习总结 我知道策略模式是对象的行为模式,其实就是对一系列级别平等的算法的封装,它不关心算法实现,让客户端去动态的

简明 状态模式(5.8)

当一个类A的某个成员变量的值变化时,可能导致多个行为表现得不同.将该成员变量封装成类型的模式,即为状态模式(state pattern). 编程技巧:以多态来重构分支结构. 设计思路:解决状态添加.状态转换.状态对行为的影响问题. 状态决定行为 先不考虑状态转换,很容易看到状态决定行为的场景."朋友来了有好酒,若是那豺狼来了,迎接它的有猎枪".不在状态,该赢的比赛都会输. 例程 4-3 又见分支结构 package property.state; public class Man{ p

Unity客户端框架笔记(状态模式和策略模式在游戏中的应用)

最近花了几天时间梳理了一下新游戏的客户端框架,虽然本身就有相对明确的方向,但是在一开始写的时候还是有些混乱,不过最终梳理完成后,个人感觉代码清爽很多. 这篇文章不是设计模式的教学,而是自己的一些想法和实践,我把代码梳理成自己喜欢的结构,保证逻辑和结构的清晰,但是这并不意味者它是符合所有人习惯的. 我之前有写过一两篇文章讨论客户端的结构,也吐槽过一些其他人的设计.可以说我在写代码之初就有一个相对明确的方向,多年的经验也可以告诉我什么样的代码是漂亮的,什么样的代码是有坏味道的. 首先我把客户端结构分

大话设计模式读书笔记--12.状态模式

定义 状态模式定义: 当一个对象的内在状态改变时,允许改变其行为,这个对象看起来改变了其类 消除庞大的条件分支,将特定状态的行为放入一个对象中 生活中:开灯和关灯是两个状态 模式结构 Context: 上下文环境,维护一个状态实例,定义当前的状态 State: 抽象状态类,定义一个接口,封装与Context的一个特定状态相关的行为 ConcreteState:具体状态.实现Context的一个特定状态相关的行为 代码实现 场景: 12店之前是休闲状态, 之后是忙碌状态 点击下载代码 特点及使用场

设计模式整理_状态模式

状态模式允许对象在内部状态改变的时候,改变它的行为,对象看起来好像修改了它的类.因为这个模式将状态封装成为独立的类,并将动作委托到代表当前状态的对象,而行为会随着内部状态而改变. 在状态模式中,Context内部持有状态,State接口定义了一个所有具体状态的共同接口,任何状态都实现这个相同的接口,这样一来,各个状态可以互相替换.具体状态实现状态接口,所以当Context改变状态的时候,行为也跟着改变.而不管在什么时候,只要有人调用Context的具体方法,它就会用来委托状态处理,下面用具体事例

大量逻辑判断优化的思路——责任链模式复习总结及其和状态模式对比

俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的总结知识点如下: 责任链模式概念和例子 使用的条件 和状态模式的比较分析 责任链的优缺点 纯的责任链和不纯的责任链 javax.servlet.Filter#doFilter()方法源码分析 基于AOP思想,模拟一个拦截器 前面说了一个状态模式,总结过程中发现和这个责任链的使用场景很类似,都是为了解耦大量复杂业务逻辑判断的,那么他们有什么不同呢?回忆状态模式——状态模式允许通过改变对象的内部状态而改变对象自身的行为,这个对象

第十六章 状态模式

好处:将与特定状态相关的行为局部化,并将不同状态的行为分割开来. 当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式. /** * Created by hero on 16-4-4. */ public abstract class State { public abstract void handle(Context context); } /** * Created by hero on 16-4-4. */ public class Con