除了较早的答案之外,请注意还有更多的可能性。首先是将模板方法分离到自己的类中:
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
更方便的使用 lambda 或方法引用。
您还可以组合这些方法:定义接口并提供一种从 lambda 构造它的方法:
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();
}
};
}
}
Java 8 中的Collector
接口以类似的方式实现。现在,根据用户的偏好,他们可以直接实现接口,也可以在Flow.of(...)
那里使用并传递 lambda 或方法引用。