模板方法模式是一种行为型设计模式,它定义了一个算法骨架,将算法的一些步骤延迟到子类中实现。模板方法允许子类在不改变算法结构的情况下重新定义算法的某些步骤。它提供了一种模板或蓝图,用于创建具有相似行为但具体实现有所不同的一组相关对象。
模板方法模式的核心思想是将算法的结构和流程定义在一个抽象的父类中,然后在具体子类中实现具体步骤。这样做的好处是可以保持算法的一致性,同时允许子类根据需要来实现或重写部分步骤。
模板方法模式的主要参与者包括:
-
抽象模板类(Abstract Template): 抽象模板类定义了一个算法的骨架,其中包含了一组抽象方法和具体方法。抽象方法由子类实现,而具体方法通常包含算法的通用步骤。
-
具体子类(Concrete Subclasses): 具体子类是抽象模板类的派生类,它们负责实现抽象方法,以定义算法的具体步骤。每个具体子类可以根据需要来实现或重写这些方法。
模板方法模式的优点包括:
- 封装不变部分: 模板方法将算法的不变部分封装在父类中,可以确保这些部分在各个子类中的一致性,减少了重复代码。
- 扩展可变部分: 子类可以根据需要扩展或重写算法的可变部分,实现自己的逻辑。
- 高层算法逻辑清晰: 模板方法将高层算法的逻辑从具体实现中分离出来,使得算法的逻辑结构更清晰可读。
模板方法模式通常应用在以下情况:
- 当多个类有相似的行为,但具体实现不同,可以将共同的行为提取到抽象模板类中。
- 当需要在不同的上下文中使用相同的算法,但具体步骤可能不同,可以使用模板方法来定义算法的骨架,然后在不同的子类中实现具体步骤。
下面是一个简单的Java示例,演示模板方法模式的应用。假设我们有一个制作咖啡和茶的过程,其中部分步骤是相同的,但某些步骤因饮料而异。
// 抽象模板类
abstract class Beverage {
// 制作饮料的模板方法
public final void prepareBeverage() {
boilWater();
brew();
pourInCup();
addCondiments();
}
// 具体方法
private void boilWater() {
System.out.println("烧开水");
}
private void pourInCup() {
System.out.println("倒入杯中");
}
// 抽象方法,由子类实现
abstract void brew();
abstract void addCondiments();
}
// 具体子类 - 咖啡
class Coffee extends Beverage {
@Override
void brew() {
System.out.println("用沸水冲泡咖啡");
}
@Override
void addCondiments() {
System.out.println("加入糖和牛奶");
}
}
// 具体子类 - 茶
class Tea extends Beverage {
@Override
void brew() {
System.out.println("用沸水浸泡茶叶");
}
@Override
void addCondiments() {
System.out.println("加入柠檬");
}
}
public class Main {
public static void main(String[] args) {
Beverage coffee = new Coffee();
coffee.prepareBeverage();
System.out.println();
Beverage tea = new Tea();
tea.prepareBeverage();
}
}
运行结果:
在这个示例中,Beverage
是抽象模板类,定义了制作饮料的模板方法 prepareBeverage()
,其中包含了烧开水、冲泡、倒入杯中和加入调料等步骤。具体的饮料类(Coffee
和Tea
)继承自抽象模板类,并实现了特定的冲泡和加入调料方法。客户端代码可以通过创建具体的饮料对象并调用 prepareBeverage()
方法来制作咖啡和茶,而无需关心每个步骤的具体实现。这就是模板方法模式的典型应用。