以前の回答に加えて、さらに多くの可能性があることに注意してください。まず、テンプレート メソッドを独自のクラスに分離します。
public interface Flow {
void phase1();
void phase2();
}
public final class FlowManager {
private final Flow flow;
public FlowManager(Flow flow) {
this.flow = flow;
}
public void startFlow() {
flow.phase1();
flow.phase2();
}
}
すでにメソッドを使用している場合は、インターフェースもFlowManager.phaseX
実装することができます。Flow
public final class FlowManager implements Flow {
private final Flow flow;
public FlowManager(Flow flow) {
this.flow = flow;
}
public void startFlow() {
flow.phase1();
flow.phase2();
}
@Override
public void phase1() {
flow.phase1();
}
@Override
public void phase2() {
flow.phase2();
}
}
Flow
このようにして、ユーザーがインターフェイスを実装する必要があることを明示的に通知しますがstartFlow
、最終クラスで宣言されているため、テンプレート メソッドを変更することはできません。
Java 8 では、問題を解決するための新しい機能パターンが追加されています。
public final class FlowManager {
private final Runnable phase1;
private final Runnable phase2;
public FlowManager(Runnable phase1, Runnable phase2) {
this.phase1 = phase1;
this.phase2 = phase2;
}
public void startFlow() {
phase1.run();
phase2.run();
}
public void phase1() {
phase1.run();
}
public void phase2() {
phase2.run();
}
}
このコードは Java 8 より前でも機能しますが、今FlowManager
ではラムダまたはメソッド参照を使用して作成できるため、はるかに便利です。
アプローチを組み合わせることもできます。インターフェイスを定義し、ラムダから構築する方法を提供します。
public interface Flow {
void phase1();
void phase2();
static Flow of(Runnable phase1, Runnable phase2) {
return new Flow() {
@Override
public void phase1() {
phase1.run();
}
@Override
public void phase2() {
phase2.run();
}
};
}
}
Collector
Java 8のインターフェースも同様の方法で実装されています。ユーザーの好みに応じて、インターフェイスを直接実装するかFlow.of(...)
、そこにラムダまたはメソッド参照を使用して渡すことができます。