它显然是一个有限状态机的例子,但最好结合条件而不是为每个组合创建一个新条件。我不喜欢 Wikipedia 上状态模式的 Java 示例,因为状态知道其他状态,这在很多情况下都没有意义。跟踪从状态、适用条件和到状态的转换表有助于解决该问题。
面向对象有限状态机的两分钱。您可以在 OO 方面进行一些改进,但它可以让想法得到传达。
class Transition {
State from;
Set<Condition> conditions;
State to;
}
class State {
String state;
}
class Condition {
String condition;
}
可以使用上述类型构建状态机。没有错误检查,但是如果在某些情况下找不到下一个状态,您可以抛出异常或其他东西。
class StateMachine {
List<Transition> transitions;
State current;
StateMachine(State start, List<Transition> transitions) {
this.current = start;
this.transitions = transitions;
}
void apply(Set<Condition> conditions) {
current = getNextState(conditions);
}
State getNextState(Set<Condition> conditions) {
for(Transition transition : transitions) {
boolean currentStateMatches = transition.from.equals(current);
boolean conditionsMatch = transition.conditions.equals(conditions);
if(currentStateMatches && conditionsMatch) {
return transition.to;
}
}
return null;
}
}
和一个测试运行:
编辑:根据您的评论,有更多的过渡和新的状态:
State one = new State("one");
State two = new State("two");
State three = new State("three");
Condition sunday = new Condition("Sunday");
Condition raining = new Condition("Raining");
Condition notSunday = new Condition("Not Sunday");
Condition notRaining = new Condition("Not Raining");
List<Transition> transitions = new ArrayList<Transition>();
transitions.add(one, new Set(sunday), three);
transitions.add(one, new Set(sunday), two); // <<--- Invalid, cant go to two and three
transitions.add(one, new Set(raining), three);
transitions.add(one, new Set(sunday, raining), three);
transitions.add(one, new Set(notSunday, notRaining), three);
StateMachine machine = new StateMachine(one, transitions);
System.out.print(machine.current); // "one"
machine.apply(new Set(sunday, raining));
System.out.print(machine.current); // "three
在一个相当大的项目中使用状态机时,我有过一段痛苦的经历。问题在于复合状态。就像您提到的复合条件(周日和下雨)一样,技术上可能存在复合状态,可以进一步分解为单位状态。在您的情况下可能会或可能不会出现这种情况,但仍然值得一提。如果是这种情况,最好修改经典的有限状态机并使用一组状态而不是单个状态来表示 from 和 to 状态。如果你的 N 很大,这将有助于保持理智水平不变。想想 hotmail 文件夹与 gmail 标签。然后转换表将显示为
Transition(Set<State> from, Set<Condition> conditions, Set<State> to)