【问题标题】:How to create a simple state machine in java如何在java中创建一个简单的状态机
【发布时间】:2011-04-26 12:28:18
【问题描述】:

我目前正在学习 java,想知道如何以 OO 方式控制状态。我实现了一个 Pong 应用程序。如果我想要像游戏和菜单这样的多个状态,并且这些状态中的每一个都必须执行启动、停止和运行,我将如何实现这一点以及如何在这些状态之间切换。

我知道我可以简单地输入一个大的 switch 语句,但是实现它的最佳方法是什么?

我希望能够在游戏状态下切换到菜单状态,反之亦然。

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Pong extends Applet implements Runnable, KeyListener{

    public void start ()
    {
        setSize(screen);
        setFocusable(true);
        Thread th = new Thread (this);
        th.start ();
    }

    public void stop()
    {
    }
    //Etc..
}

【问题讨论】:

    标签: java state-machine


    【解决方案1】:

    您可以使用枚举模拟基本的 FSM(有限状态机):

    public enum State {
    
        ONE {
            @Override
            public Set<State> possibleFollowUps() {
                return EnumSet.of(TWO, THREE);
            }
        },
    
        TWO {
            @Override
            public Set<State> possibleFollowUps() {
                return EnumSet.of(THREE);
            }
        },
    
        THREE // final state 
    
        ;
        public Set<State> possibleFollowUps() {
            return EnumSet.noneOf(State.class);
        }
    
    }
    

    虽然如果事情变得更复杂,生成它的代码会非常冗长,但好的部分是您可以获得编译时安全性、线程安全性和高性能。

    【讨论】:

    • 注意:当覆盖特定枚举中的方法时,它们的类是不同的。 (在这种情况下 THREE.getClass() 是 State,TWO.getClass() 可能是 State$2)
    • 这段代码启发了你艰难的过程,尤其是在java中。谢谢。
    • @Sean:注意到 Asaf 的评论,我想知道,您是否会看到将构造函数中可能的后续状态传递给不同状态而不是覆盖方法的任何缺点? (比如ONE(EnumSet.of(TWO, THREE)), TWO(EnumSet.of(THREE))...
    • 好的,我自己想通了。枚举的值显然不允许在枚举本身的构造函数中使用。 :p
    • @TomFink 完全正确。否则你的版本当然会更好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-19
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    • 2020-05-30
    • 2016-06-09
    相关资源
    最近更新 更多