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);
}