Java 改进状态机

Java 改进状态机,java,switch-statement,state-machine,Java,Switch Statement,State Machine,因此,我将这个状态机(在下一个代码中,一些状态由于尚未完成而丢失)设置为许多几乎相同的状态。 我相信一定有更好的方法来实现这一点,但我找不到(可能是上课,但我不确定) 有什么我可以应用的模式吗?还是什么 提前感谢。请注意每个状态下的代码,该代码测试输入字符,如果匹配,则接受输入并设置下一个状态: if (c == ????) { builder.append(c); firstState = ???? } 您可以将此逻辑移到一个方法中,并为每个状态/输入组合从开关中删除三行代码

因此,我将这个状态机(在下一个代码中,一些状态由于尚未完成而丢失)设置为许多几乎相同的状态。 我相信一定有更好的方法来实现这一点,但我找不到(可能是上课,但我不确定)

有什么我可以应用的模式吗?还是什么


提前感谢。

请注意每个状态下的代码,该代码测试输入字符,如果匹配,则接受输入并设置下一个状态:

if (c == ????) {
    builder.append(c);
    firstState = ????
}
您可以将此逻辑移到一个方法中,并为每个状态/输入组合从
开关中删除三行代码

此外,请注意,每个案例都有:

    else
        firstState = FirstParserState.ERROR;
通过使用
nextState
变量,可以从每个状态中消除这两行。在
开关之前
设置
nextState=FirstParserState.ERROR
。当输入匹配时,您可以在
nextState
中设置新状态,而不是直接在
firstState
中设置。
如果没有匹配的输入,则各个状态不需要执行任何特殊操作,因为
nextState
将已经是
FirstParserState.ERROR
。然后在
开关之后
设置
firstParserState=nextState
为下一次迭代做准备。

需要一个状态表,将当前状态和当前输入字符映射到下一个状态。然后你所要做的就是打开下一个状态并采取适当的措施。

我认为你应该去掉开关盒的部分。您可以实现状态机设计模式,而无需为每个状态创建一个类,如果您有多个状态,则有一个更优雅的解决方案:基于枚举的状态机

Enum类实现了ParserStateListener.java
接口,该接口包含可以更改对象状态的方法

public enum FirstParserState implements ParserStateListener{

INITIAL{
    public void onEventChange(char c, StringBuilder builder, FirstParserState nextState) {
        if (c == 'g') {
            builder.append(c);
            nextState = FirstParserState.METHOD_G;
        } else if (c == 'p') {
            builder.append(c);
            nextState = FirstParserState.METHOD_P;
        } else
            nextState = FirstParserState.ERROR;

    }
},METHOD_G{
    public void onEventChange(char c, StringBuilder builder, FirstParserState nextState) {
        if (c == 'e') {
            builder.append(c);
            nextState = FirstParserState.METHOD_E;
        } else
            nextState = FirstParserState.ERROR;

    }
},METHOD_E{
    public void onEventChange(char c, StringBuilder builder, FirstParserState nextState) {
        if (c == 't') {
            builder.append(c);
            nextState = FirstParserState.METHOD_T;
        } else
            nextState = FirstParserState.ERROR;

    }
},ERROR{
    public void onEventChange(char c, StringBuilder sb, FirstParserState nextState) {
        // TODO Auto-generated method stub

    }
};

}
这是一个侦听器类,用于保存将更改对象状态的操作

public interface ParserStateListener {

public void onEventChange(char c, StringBuilder sb, FirstParserState nextState);

}
然后,您只需编写客户端代码:

 public void doOperations(){
    StringBuilder sb = new StringBuilder();

    FirstParserState firstParserState = FirstParserState.INITIAL;
    firstParserState.onEventChange(c, sb, firstParserState);        

}

这种方法只是第一次看我不知道你的确切要求。如果您需要多次调用
onEventChange(c,sb,firstParserState)
方法,并且如果您已经知道了转换路径,那么您可以将路由放在集合中,并通过调用此方法进行迭代

您到底想要实现什么?我必须解析HTTP请求(使用状态机)。这将解析第一行(它没有完成的代码)。虽然EJP的答案可能是最简单和最有效的实现方式,但另一种选择是状态模式。每个州由州的一个实例表示,州负责执行1。实际工作(您的
if(c==x){build.append(c);}
stuff)2。状态改变谢谢,但是有没有办法避免在每个状态下创建类(当使用状态模式时)?谢谢,我可能会尝试一下,这取决于状态模式的可能实现。
 public void doOperations(){
    StringBuilder sb = new StringBuilder();

    FirstParserState firstParserState = FirstParserState.INITIAL;
    firstParserState.onEventChange(c, sb, firstParserState);        

}