不適切なパターンを使用しているため、問題が発生しています。
Task
は次の状態に戻ってはなりません。フローを制御するには、State
の行列を使用する必要があります。このようにして、あなたの流れは仕事の中で絡み合っておらず、State
はフローシステムにはプライベートなままです。
Task
にフローを制御させたい場合は、フローコントローラに影響を与える何らかのもの(おそらく成功/失敗)を返さなければなりません。彼らは次の状態を定義するべきではありません影響次の状態。
を追加しました
は、ここで私が言いたいのやや不自然な例です。各State
にTask
がどのように接続されているかに注目し、フローは各状態遷移を保持するだけの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);
}
}
}
タスクの実行からのフロー制御を私は乗り越えようとしていました。
いいえ、一部の列挙定数をパブリックに、一部をプライベートにマークすることはできません。 –
この場合は、古いJavaのenumを使うことができます。いくつかの最終静的定数を持つクラスだけです。 – Marcelo
実際には、何もマークすることはできません。彼らは「公的」であり、それだけです。 –