有限状态机(FSM)的Java 演示
本文从简单的样例入手,逐步演变成很复杂的程序。
在简明 状态模式(5.8)中,状态之间的变换由外界控制,或者说。多种状态是切割的、无关的。状态模式最有趣的地方正是讨论其状态的变迁。
1.引子
空调(air-condition)的遥控器有两个button(很多其它的button在后面的样例中引入),power/电源键和cool/制冷键。
空调的执行呈现3个状态。停止/Off、仅送风/FanOnly、制冷/Cool。起始状态为Off,状态变化图例如以下所看到的。
这是简化的有限状态机(Finite State Machine、FSM或者Finite State Automata)图形,使用了状态图的3个元素:①气泡,表示状态(state)。②连接状态的箭头表示转换(transition)。③箭头上的标记前者为事件(event)。
状态的转换,看图说话。按power键,则Off→FanOnly、Cool→Off等。按cool,则Off→Off (没有画出来,喜欢全面一点就自己画吧)。
对于这样的简单的状态的转换,yqj2065还是喜欢分支语句。,简洁明快。
- 例程 4-5 简洁明快
- package property.state.stateMachine;
- import static tool.Print.*;//pln
- /**
- * 空调Aircon。简单的模型:
- * 遥控器有两个button(很多其它的button在以下的样例中引入),power电源键和cool制冷键。
- * 空调的执行呈现3个状态。停止/Off、仅送风/FanOnly、制冷/Cool。
- * 起始状态为Off
- * @author (yqj2065)
- * @version 0.1
- */
- public class Aircon0{
- // off,FanOnly。AC
- private int state=0;//起始状态为Off
- public int getState(){return state;}
- //两个Action
- public void power(){//按power键
- if(state==0){//off
- state=1;
- pln("start Fan");
- }else if(state==1){//FanOnly
- state=0;
- pln("stop Fan");
- }else{
- state=0;
- pln("stop Cool");
- }
- }
- public void cool(){//按制冷键
- if(state==0){//off
- pln("nothing");
- }else if(state==1){//FanOnly
- state=2;
- pln("start Cool");
- }else{
- state=1;
- pln("stop Cool");
- }
- }
- }
- package property.state.stateMachine;
- public class ACCtrl{
- public static void test(){
- Aircon0 ac = new Aircon0();//power() cool()
- System.out.println("Current State:" + ac.getState());
- ac.cool();
- ac.power();
- ac.cool();
- ac.cool();
- ac.power();
- ac.power();
- }
- }
測试代码的输出:
Current State:0
nothing
start Fan
start Cool
stop Cool
stop Fan
start Fan
在此基础上,能够花10分钟练习一下,採用状态模式改动上述代码。
- 例程 4 6 enum State
- enum State0{
- OFF{
- @Override void power(){
- }
- @Override void power(){
- }
- },FANONLY{
- },
- COOL{ };
- public abstract void power();
- public abstract void cool();
- }
(本来是应该将State1作为Aircon1的内部类的。放在外边,power()等须要加入參数Aircon1,变为power(Aircon1 ac)).
如今。丰富有限状态机的细节,增添④动作(action),如事件(event)对应的动作和状态的动作。
为此,在enum State1中,除了状态模式 提取的接口外。加入了状态机的各种动作/action methode
void entry(Aircon1 ac){pln("→"+ac.state.name());}
void exit(Aircon1 ac){p(ac.state.name()+"→ ");}
void startCool(){ p("start Cool"); }
void stopCool(){ p("stop Cool"); }
void startFan(){ p("start Fan"); }
void stopFan(){ p("stop Fan"); }
每一个power(Aircon1 ac)、cool(Aircon1 ac)的方法体结构都是:
this.exit(ac);
//假设有的话。事件(event)对应的动作,如stopFan();
ac.state =OFF; //下一个状态
ac.state.entry(ac);
- package property.state.stateMachine;
- import static tool.Print.*;//pln
- /**
- * 本来是应该将State1作为Aircon1的内部类的。如今放在外边。
- * power()等须要变为power(Aircon1 ac)
- */
- public enum State1{
- OFF{
- @Override void exit(Aircon1 ac){super.exit(ac);startFan();}
- @Override void power(Aircon1 ac){
- this.exit(ac);
- ac.state =FANONLY;
- ac.state.entry(ac);
- }
- @Override void cool(Aircon1 ac){
- pln("nothing");
- }
- },FANONLY{
- @Override void power(Aircon1 ac){
- this.exit(ac);
- stopFan();
- ac.state =OFF;
- ac.state.entry(ac);
- }
- @Override void cool(Aircon1 ac){
- this.exit(ac);
- ac.state =COOL;
- ac.state.entry(ac);
- }
- },
- COOL{
- @Override void exit(Aircon1 ac){super.exit(ac);stopCool();}
- @Override void entry(Aircon1 ac){startCool();super.entry(ac);}
- @Override void power(Aircon1 ac){
- this.exit(ac);
- stopFan();
- ac.state =OFF;
- ac.state.entry(ac);
- }
- @Override void cool(Aircon1 ac){
- this.exit(ac);
- ac.state =FANONLY;
- ac.state.entry(ac);
- }
- };
- //状态模式 提取的接口
- abstract void power(Aircon1 ac);
- abstract void cool(Aircon1 ac);
- //状态机的各种动作action methode
- void entry(Aircon1 ac){pln("→"+ac.state.name());}
- void exit(Aircon1 ac){p(ac.state.name()+"→ ");}
- void startCool(){ p("start Cool"); }
- void stopCool(){ p("stop Cool"); }
- void startFan(){ p("start Fan"); }
- void stopFan(){ p("stop Fan"); }
- }
空调Aircon1的改动版本号。
- package property.state.stateMachine;
- import static tool.Print.*;//pln
- /**
- * 空调Aircon1。使用状态模式重构Aircon0。使用enum State1编写状态类层次。
- * @author (yqj2065)
- * @version 0.1
- */
- public class Aircon1{
- State1 state= State1.OFF;//private改默认。删除getState()。
- //两个Action
- public void power(){//按power键
- state.power(this);
- }
- public void cool(){//按制冷键
- state.cool(this);
- }
- /**
- * ACCtrl的代码。
- */
- public static void test(){
- Aircon1 ac = new Aircon1();
- System.out.println("Current State:" + ac.state.name());
- ac.cool();
- ac.power();
- ac.cool();
- ac.cool();
- ac.power();
- ac.power();
- ac.power();
- }
- }
相应測试操作的输出:“OFF→”表示离开OFF状态,而“→FANONLY”...
Current State:OFF
nothing
OFF→ start Fan→FANONLY
FANONLY→ start Cool→COOL
COOL→ stop Cool→FANONLY
FANONLY→ stop Fan→OFF
OFF→ start Fan→FANONLY
FANONLY→ stop Fan→OFF
2.分层状态机
对于状态较多的状态机。通常将具有很多公共的特性的状态合并到一起。比如FANONLY和COOL构成的Running状态。
状态机中的hierarchical states,我们可以使用组合模式处理。(还没有单独写组合模式,)。
可是,又不一定可以完美地使用组合模式。比如Running到Off,全部的Running的内部状态在PoverEvent时都转化到OFF。非常好;OFF到Running。不是全部Running的内部状态都要调用其entry。在使用enum(不好搞类层次)时,使用责任链吧。
楼主绘图中、考虑很多其它button中....
有限状态机(FSM)的Java 演示的更多相关文章
- 有限状态机(FSM)的Java 学习FSM
本文从简单的例子入手,逐步演变成非常复杂的程序. 在简明 状态模式(5.8)中,状态之间的变换由外界控制,或者说,多种状态是分割的.无关的.状态模式最有趣的地方正是讨论其状态的变迁. 1.引子 空调( ...
- cocos2d-x 游戏开发之有限状态机(FSM) (四)
cocos2d-x 游戏开发之有限状态机(FSM) (四) 虽然我们了解了FSM,并且可以写自己的FSM,但是有更好的工具帮我们完成这个繁琐的工作.SMC(http://smc.sourceforge ...
- Atitit. 有限状态机 fsm 状态模式
Atitit. 有限状态机 fsm 状态模式 1. 有限状态机 1 2. "状态表"和"状态轮换表" 1 3. 有限状态机概念(状态(State)事件(Even ...
- 有限状态机FSM(自动售报机Verilog实现)
有限状态机FSM(自动售报机Verilog实现) FSM 状态机就是一种能够描述具有逻辑顺序和时序顺序事件的方法. 状态机有两大类:Mealy型和Moore型. Moore型状态机的输出只与当前状态有 ...
- cocos2d-x 游戏开发之有限状态机(FSM) (三)
cocos2d-x 游戏开发之有限状态机(FSM) (三) 有限状态机简称FSM,现在我们创建一个专门的FSM类,负责管理对象(Monkey)的状态.然后Monkey类就实现了行为与状态分离.Monk ...
- cocos2d-x 游戏开发之有限状态机(FSM) (一)
cocos2d-x 游戏开发之有限状态机(FSM) (一) 参考:http://blog.csdn.net/mgphuang/article/details/5845252<Cocos2d-x游 ...
- cocos2d-x 游戏开发之有限状态机(FSM) (二)
cocos2d-x 游戏开发之有限状态机(FSM) (二) 1 状态模式
- 有限状态机FSM
有限状态机(Finite-state machine)又称有限状态自动机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型.常用与:正则表达式引擎,编译器的词法和语法分析,游戏设计,网络 ...
- [原创][FPGA]有限状态机FSM学习笔记(一)
1. 概述--何为有限状态机FSM? 有限状态机-Finite State Machine,简写为FSM,是表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用.通常 ...
随机推荐
- Django套用现成模板,导入css,js,images等文件
https://blog.csdn.net/mildddd/article/details/79557803
- JAVA-JSP内置对象之request获得参数的参数值(一个值)
相关资料:<21天学通Java Web开发> 获得参数的参数值(一个值) RequestForm3.jsp <%@ page language="java" co ...
- 基于HTML5手机登录注册表单代码
分享一款基于HTML5手机登录注册表单代码.这是一款鼠标点击注册登录按钮弹出表单,适合移动端使用.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div class=&qu ...
- docker探索-使用docker service管理swarm(十一 )
本文转自:https://www.cnblogs.com/atuotuo/p/6265541.html 1.创建一个 Docker service $ docker service create -- ...
- EM算法学习资料备忘
将学习EM算法过程中看到的好的资料汇总在这里,供以后查询.也供大家參考. 1. 这是我学习EM算法最先看的优秀的入门文章,讲的比較通俗易懂,并且举了样例来说明当中的原理.不错! http://blog ...
- FallbackFactory启动的时候抛出异常
在Hystrix做熔断的时候,开始用的是FallBack,后来为了找出为啥exception,然后就用了FallBackFactory. 但是奇怪的是,一起动就抛出异常,真的是百思不得骑姐,错了其解. ...
- git diff 的用法
git diff 对比两个文件修改的记录 不带参数的调用 git diff filename 这种是比较 工作区和暂存区 比较暂存区与最新本地版本库 git diff --cached filenam ...
- JavaScript 中 类型转换
转自 https://www.cnblogs.com/wuxiaoshang/p/5835627.html // 转换成字符型 var married = false; alert(married.t ...
- [mqtt]mqtt嵌入式移植
github eclipse paho source code: https://github.com/mqtt/mqtt.github.io/wiki/libraries STM32 mqtt移植: ...
- 将安卓手机短信导入到iPhone6 plus中
不越狱的情况下短信不能直接同步到iphone手机,视频.图片.联系人可以直接使用itools的手机搬家功能超方便从android到iphone中.短信得变通的处理才能导入. 工具: 安卓手机iPhon ...