これは明らかに有限状態マシンのケースですが、組み合わせごとに新しい条件を作成するよりも、条件を組み合わせる方が適切です。州は多くのシナリオで意味をなさない他の州について知っているため、Wikipedia の State パターンの Java の例は好きではありませんでした。from状態、適用可能なcondition(s)、およびto状態を追跡する遷移テーブルは、この問題の処理に役立ちます。
オブジェクト指向の有限状態機械に対する私の 2 セント。オブジェクト指向の面で改善できる点はありますが、アイデアは伝わります。
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
かなり大規模なプロジェクトでステート マシンを使用するという苦い経験がありました。問題は複合状態にありました。あなたが言及した複合状態 (日曜日と雨) のように、技術的には、さらに単位状態に分解できる複合状態が存在する可能性があります。これはあなたの状況に当てはまる場合とそうでない場合がありますが、それでも言及する価値があります。その場合は、従来の有限状態マシンを変更し、単一の状態ではなく状態のセットを使用して、開始状態と終了状態を表すのが最善です。N が大きい場合、これは健全性レベルをそのまま維持するのに役立ちます。hotmail フォルダと gmail タグを考えてみてください。遷移表は次のように表されます。
Transition(Set<State> from, Set<Condition> conditions, Set<State> to)