Skip to main content

模板方法模式 (Template)

场景问题​

问题案例​

考虑一个制作饮品的流程,制作咖啡和茶都需要烧水、冲泡、倒入杯中、加调料,但具体的冲泡和加调料方式不同。

不用模式的解决方案​

实现简化版本​

最直接的做法是为每种饮品写一个完整的制作方法:

public class Coffee {
public void make() {
System.out.println("烧水");
System.out.println("冲泡咖啡");
System.out.println("倒入杯中");
System.out.println("加糖和牛奶");
}
}
public class Tea {
public void make() {
System.out.println("烧水");
System.out.println("浸泡茶叶");
System.out.println("倒入杯中");
System.out.println("加柠檬");
}
}

使用示例​

Coffee coffee = new Coffee();
coffee.make();
Tea tea = new Tea();
tea.make();

有何问题​

  1. 代码重复,流程难以维护。
  2. 扩展新饮品需复制粘贴流程,易出错。
  3. 难以复用通用流程。

解决方案​

模板方法模式的定义​

定义一个操作中的算法骨架,将一些步骤延迟到子类中,使得子类可以不改变算法结构即可重定义该算法的某些特定步骤。

应用模板方法模式的思路​

  • 抽象父类定义模板方法,封装通用流程。
  • 具体子类实现差异化步骤。
  • 子类可选择性重写部分步骤。

模板方法模式的结构​

  • AbstractClass:抽象类,定义模板方法和基本步骤。
  • ConcreteClassA/B:具体子类,实现差异化步骤。

模板方法模式的实现​

// 抽象类
public abstract class Beverage {
// 模板方法
public final void make() {
boilWater();
brew();
pourInCup();
addCondiments();
}
private void boilWater() { System.out.println("烧水"); }
protected abstract void brew();
private void pourInCup() { System.out.println("倒入杯中"); }
protected abstract void addCondiments();
}

// 具体子类:咖啡
public class Coffee extends Beverage {
protected void brew() { System.out.println("冲泡咖啡"); }
protected void addCondiments() { System.out.println("加糖和牛奶"); }
}

// 具体子类:茶
public class Tea extends Beverage {
protected void brew() { System.out.println("浸泡茶叶"); }
protected void addCondiments() { System.out.println("加柠檬"); }
}

使用示例​

public class Client {
public static void main(String[] args) {
Beverage coffee = new Coffee();
coffee.make();
Beverage tea = new Tea();
tea.make();
}
}

模板方法重写示例​

示例结构​


示例代码​

见上文"模板方法模式的实现"部分。


模式讲解​

模板方法模式的功能​

  • 复用通用流程,便于维护。
  • 子类灵活扩展差异化步骤。
  • 满足开闭原则。

实现成接口​

  • 抽象类定义模板方法和基本步骤。

使用工厂方法​

  • 可结合工厂方法模式,统一创建子类对象。

切换产品簇​

  • 可用于切换不同的流程模板,如不同饮品制作流程。

执行时序图​