设计模式学习(十四):模板方法
作者:Grey
原文地址:
模板方法
模板方法是一种行为型模式。
假设我们要实现一个游戏,这个游戏有「初始化」,「启动」,「结束」三个方法,那么可以定义一个游戏的模板:
public abstract class Game {
// 游戏初始化
protected abstract void init();
// 游戏开始
protected abstract void start();
// 游戏结束
protected abstract void end();
// 玩游戏方法
protected final void play() {
init();
start();
end();
}
}
每种类似这样结构(有「初始化」,「启动」,「结束」三个步骤)的游戏都可以继承这个类来实现这三个方法,比如:
BasketballGame
public class BasketballGame extends Game {
@Override
protected void init() {
System.out.println("basketball init");
}
@Override
protected void start() {
System.out.println("basketball start");
}
@Override
protected void end() {
System.out.println("basketball end");
}
}
FootballGame
public class FootballGame extends Game {
@Override
protected void init() {
System.out.println("football init");
}
@Override
protected void start() {
System.out.println("football start");
}
@Override
protected void end() {
System.out.println("football end");
}
}
主方法在调用的时候,直接调用其 play()
方法,就可以了。
Game basketballGame = new BasketballGame();
basketballGame.play();
Game footballGame = new FootballGame();
footballGame.play();
本示例的 UML 图如下:
另外一个例子,
假设我们要设计一系列的测试用例,然后运行这些测试用例的的测试方法,可以抽象出一个 TestCase 的模板方法,代码如下
public abstract class TestCase {
public void run() {
if (doTest()) {
System.out.println("Test succeed.");
} else {
System.out.println("Test failed.");
}
}
public abstract boolean doTest();
}
其中 TestCase 是抽象类,doTest()
是抽象方法,这样每个具体的测试用例,就只需要继承这个抽象类,并且实现其具体的 doTest()
方法即可。
public class UserServiceTest extends TestCase {
@Override
public boolean doTest() {
System.out.println("do test...");
return false;
}
}
主方法在调用的时候,直接把一系列的 TestCase 进行遍历并执行 run()
方法即可
public class JunitApplication {
private static final List<TestCase> testCases = new ArrayList<>();
public static void register(TestCase testCase) {
testCases.add(testCase);
}
public static final void main(String[] args) {
for (TestCase c : testCases) {
c.run();
}
}
}
模板方法实际应用场景举例
-
Spring 中的 RestTemplate 、JDBCTemplate 等。
-
Java SE 中的
Collections.sort()
方法也可以看成模板方法。 -
Java SE 中的 AbstractList 类定义了一些模板方法,ArrayList 作为子类实现了对应的模板方法。
-
MyBatis 中的 BaseExecutor 定义了模板方法,子类 ReuseExecutor 、SimpleExecutor 、BatchExecutor 和 ClosedExecutor 实现了对应的模板方法
-
Redission 的红锁和联锁设计。