間違ったパターンを使用しているため、問題が発生しています。
あなたTask
の s は次の状態を返すべきではありません。State
フローを制御するには、s の行列を使用する必要があります。こうすることで、フローがタスク内で絡まることはなく、State
s はフロー システムに対して非公開のままです。
フローを制御したい場合はTask
、フローコントローラーに影響を与えるために何か (おそらく成功/失敗) を返す必要があります。次の状態を定義するのではなく、次の状態に影響を与える必要があります。
追加した
これは、私が言いたいことの少し不自然な例です。Task
がそれぞれに接続され、各状態遷移を保持するだけState
の によってフローが制御されることに注目してください。Map
返された結果に一致するようにトークンの努力をしましたが、それは問題を複雑にしすぎているのではないかと思います.フローと状態の分離を受け入れると、私が説明しようとしていることを理解できます.
public class Test {
public void test() {
new Thread(new Engine()).start();
}
static final Map<State, State> flow = new HashMap<>();
static {
flow.put(State.Start, State.A);
flow.put(State.A, State.B);
flow.put(State.B, State.Finished);
}
public static class Engine implements Runnable {
State state = State.Start;
@Override
public void run() {
while (state != State.Finished) {
System.out.println("State: "+state);
// Perform all tasks of this state.
for ( Task task : state.tasks ) {
System.out.println("Task: "+task);
Result result = Result.Start;
// Keep performing until completed.
while ( result != Result.Completed ) {
System.out.println("Result: "+result);
result = result.perform(task);
}
System.out.println("Result: "+result);
}
// All tasks performed! Next state.
state = flow.get(state);
}
System.out.println("State: "+state);
}
}
enum State {
Start,
A(Task.One, Task.Two),
B(Task.Two),
Finished;
Iterable<Task> tasks;
State(Task... tasks) {
this.tasks = Arrays.asList(tasks);
}
}
enum Result {
Start {
@Override
Result perform(Task t) {
return t.initialise();
}
},
Executing {
@Override
Result perform(Task t) {
return t.execute();
}
},
Finalising {
@Override
Result perform(Task t) {
return t.finalise();
}
},
Completed {
@Override
Result perform(Task t) {
// Stop there.
return Completed;
}
};
abstract Result perform(Task t);
}
enum Task {
One {
@Override
Result initialise() {
return Result.Executing;
}
@Override
Result execute() {
return Result.Finalising;
}
@Override
Result finalise() {
return Result.Completed;
}
},
Two {
@Override
Result initialise() {
return Result.Executing;
}
@Override
Result execute() {
return Result.Finalising;
}
@Override
Result finalise() {
return Result.Completed;
}
};
abstract Result initialise();
abstract Result execute();
abstract Result finalise();
}
public static void main(String args[]) {
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
}
追加した
取得したタスク メソッドの結果を通じてフローを制御するという要件を削除することで、これを簡素化します。
public class Test {
public void test() {
new Thread(new Engine()).start();
}
static final Map<State, State> flow = new HashMap<>();
static {
flow.put(State.Start, State.A);
flow.put(State.A, State.B);
flow.put(State.B, State.Finished);
}
public static class Engine implements Runnable {
State state = State.Start;
@Override
public void run() {
while (state != State.Finished) {
System.out.println("State: "+state);
// Perform all tasks of this state.
for ( Task task : state.tasks ) {
System.out.println("Task: "+task);
task.initialise();
task.execute();
task.finalise();
}
// All tasks performed! Next state.
state = flow.get(state);
}
System.out.println("State: "+state);
}
}
enum State {
Start,
A(Task.One, Task.Two),
B(Task.Two),
Finished;
Iterable<Task> tasks;
State(Task... tasks) {
this.tasks = Arrays.asList(tasks);
}
}
enum Task {
One {
@Override
void execute() {
}
},
Two {
@Override
void execute() {
}
};
// Nothing by default.
void initialise() {
}
abstract void execute();
// Nothing by default.
void finalise() {
}
}
public static void main(String args[]) {
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
}
これは、私が理解しようとしていたタスク実行からのフロー制御の分離を示していると思います。