模版模式(Template Pattern)是一种行为设计模式,它在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中。模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
模版模式的结构
- 抽象类(Abstract Class) :定义模版方法(通常为
final,防止子类修改算法结构)和若干抽象方法(由子类实现),也可以包含一些通用实现。 - 具体子类(Concrete Class) :实现抽象方法,完成特定步骤。
案例:制作饮料
假设我们有制作茶和咖啡的流程,它们的步骤类似:
- 烧水
- 冲泡(茶用茶叶,咖啡用咖啡粉)
- 倒入杯中
- 添加调料(茶可能加柠檬,咖啡可能加糖和牛奶)
我们可以用模版模式将相同的步骤放在抽象类中,不同的步骤交给子类实现。
代码示例(Java)
java
// 抽象类:饮料制作流程
abstract class Beverage {
// 模版方法,定义算法骨架
public final void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
// 通用步骤
private void boilWater() {
System.out.println("烧水");
}
private void pourInCup() {
System.out.println("倒入杯中");
}
// 抽象步骤,由子类实现
protected abstract void brew();
protected abstract void addCondiments();
// 钩子方法,子类可以覆盖,用于控制是否执行某些步骤
protected boolean customerWantsCondiments() {
return true; // 默认需要调料
}
}
// 具体子类:茶
class Tea extends Beverage {
@Override
protected void brew() {
System.out.println("浸泡茶叶");
}
@Override
protected void addCondiments() {
System.out.println("加入柠檬");
}
}
// 具体子类:咖啡
class Coffee extends Beverage {
@Override
protected void brew() {
System.out.println("冲泡咖啡粉");
}
@Override
protected void addCondiments() {
System.out.println("加入糖和牛奶");
}
// 覆盖钩子方法,决定是否加调料
@Override
protected boolean customerWantsCondiments() {
// 这里可以询问用户,简单返回 true
return true;
}
}
// 测试类
public class TemplatePatternDemo {
public static void main(String[] args) {
System.out.println("制作茶:");
Beverage tea = new Tea();
tea.prepareRecipe();
System.out.println("\n制作咖啡:");
Beverage coffee = new Coffee();
coffee.prepareRecipe();
}
}
运行结果
text
制作茶:
烧水
浸泡茶叶
倒入杯中
加入柠檬
制作咖啡:
烧水
冲泡咖啡粉
倒入杯中
加入糖和牛奶
模版模式的优点
- 代码复用:将公共代码放在抽象类中,避免重复。
- 扩展性:子类只需实现必要步骤,算法结构固定。
- 控制反转:父类调用子类的方法,实现反向控制。
适用场景
- 多个类有相同的算法步骤,但部分步骤实现不同。
- 希望控制子类扩展,不允许修改算法整体结构。
- 需要提取公共行为到基类,避免代码重复。
模版模式在框架和库中非常常见,例如 Java 的 AbstractList、HttpServlet 的 service 方法等。