上代码:
abstract class Game {
// 模板方法定义了游戏的基本流程
public final void play() {
initialize();
if (isEarlyGame()) {
earlyGame();
return;
}
startPlay();
endPlay();
}
// 初始化游戏
abstract void initialize();
// 开始游戏
abstract void startPlay();
// 结束游戏
abstract void endPlay();
// 钩子方法,子类可以选择性实现以影响执行顺序
boolean isEarlyGame() {
return false;
}
// 钩子方法,子类可以选择性实现以影响执行顺序
void earlyGame() {
// 默认情况下,不执行早期游戏逻辑
}
}
class Chess extends Game {
@Override
void initialize() {
System.out.println("初始化国际象棋");
}
@Override
void startPlay() {
System.out.println("开始国际象棋");
}
@Override
void endPlay() {
System.out.println("结束国际象棋");
}
}
class Monopoly extends Game {
private boolean endEarly;
// 设置是否提前结束游戏
public void setEndEarly(boolean endEarly) {
this.endEarly = endEarly;
}
@Override
void initialize() {
System.out.println("初始化大富翁");
}
@Override
void startPlay() {
System.out.println("开始大富翁");
}
@Override
void endPlay() {
System.out.println("结束大富翁");
}
@Override
boolean isEarlyGame() {
return endEarly;
}
@Override
void earlyGame() {
System.out.println("执行早期大富翁逻辑并结束!");
}
}
public class TemplateMethodExample {
public static void main(String[] args) {
Game chessGame = new Chess();
Game monopolyGame = new Monopoly();
System.out.println("国际象棋游戏流程:");
chessGame.play();
System.out.println("\n大富翁游戏流程(提前结束):");
Monopoly monopolyGameEarly = new Monopoly();
monopolyGameEarly.setEndEarly(true);
monopolyGameEarly.play();
}
}
运行结果:
国际象棋游戏流程:
初始化国际象棋
开始国际象棋
结束国际象棋大富翁游戏流程(提前结束):
初始化大富翁
执行早期大富翁逻辑并结束!
在我们的抽象类中isEarlyGame()的返回值就是影响了模板方法的执行结 果,该方法就叫做钩子方法(Hook Method)。有了钩子方法模板方法模式才算完美,大家 可以想想,由子类的一个方法返回值决定公共部分的执行结果,是不是很有吸引力!
模板方法在一些开源框架中应用非常多,它提供了一个抽象类,然后开源框架写了一堆子类。在《××× In Action》中就说明了,如果你需要扩展功能,可以继承这个抽象类,然后 覆写protected方法,再然后就是调用一个类似execute方法,就完成你的扩展开发,非常容易 扩展的一种模式。