模板方法模式(Template Method Pattern)是一种行为型设计模式,其主要目的是定义一个算法的骨架,而将一些步骤的具体实现延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下重新定义算法中的某些步骤。
是一种基于继承的代码复用技术,它是一种类行为模式. 模板方法模式其结构中只存在父类与子类之间的继承关系.
模板方法的作用主要是提高程序的复用性 和扩展性:
- 复用指的是,所有的子类可以复用父类中提供的模板方法代码
- 扩展指的是,框架通过模板模式提供功能扩展点,让框架用户可以在不修改框架源码的情况下,基于扩展点定制化框架的功能.
说白了,就是在父类中定义了一系列的方法和步骤。在子类中重写了其中一部分的方法,导致在执行整个任务流程的时候,没有重写的方法走的是父类中的逻辑,重写了的,走的是子类中的逻辑。这样我们就可以定义不同的子类执行同一流水线上的工作,但是可以定制其中的某些步骤。
主要角色:
-
抽象类(Abstract Class): 定义了算法的骨架,包含了一系列步骤,其中的某些步骤由子类负责实现。
-
具体类(Concrete Class): 实现了抽象类中定义的某些步骤,以完成算法中的具体细节。
示例:
考虑一个制作咖啡和茶的例子,其中冲泡饮料的步骤是相似的,可以使用模板方法模式来实现。
java
package com.luke.designpatterns.templateMethod;
// 抽象类 - 饮料制备模板
abstract class BeverageTemplate {
// 模板方法,定义了制备饮料的算法骨架
public final void prepareBeverage() {
boilWater();
brew();
pourInCup();
addCondiments();
}
// 具体步骤由子类实现
protected abstract void brew();
protected abstract void addCondiments();
// 公共步骤
private void boilWater() {
System.out.println("Boiling water");
}
private void pourInCup() {
System.out.println("Pouring into cup");
}
}
// 具体类 - 咖啡
class Coffee extends BeverageTemplate {
@Override
protected void brew() {
System.out.println("Brewing coffee grounds");
}
@Override
protected void addCondiments() {
System.out.println("Adding sugar and milk");
}
}
// 具体类 - 茶
class Tea extends BeverageTemplate {
@Override
protected void brew() {
System.out.println("Steeping the tea");
}
@Override
protected void addCondiments() {
System.out.println("Adding lemon");
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
// 通过调用模板方法制备饮料
BeverageTemplate coffee = new Coffee();
BeverageTemplate tea = new Tea();
System.out.println("Making coffee:");
coffee.prepareBeverage();
System.out.println("\nMaking tea:");
tea.prepareBeverage();
}
}
在这个例子中,BeverageTemplate
是抽象类,定义了饮料制备的算法骨架,其中包含了一系列步骤,如煮水、冲泡、倒入杯中和加调料等。Coffee
和 Tea
是具体类,分别实现了咖啡和茶的具体步骤。客户端代码可以通过创建具体类的实例并调用prepareBeverage
方法来制备咖啡和茶。
模板方法模式的优点在于将公共的算法流程封装在抽象类中,避免了代码重复 ,并且允许子类通过实现特定的步骤来定制算法的某些部分 。这样,算法的整体结构保持不变,但具体实现可以灵活变化。
使用场景
-
框架设计: 在软件框架的设计中,模板方法模式经常用于定义框架的骨架,而具体的实现细节则由子类来完成。例如,Web框架中的请求处理流程或游戏开发中的状态机设计。
-
文档生成: 在文档生成工具中,可以使用模板方法模式定义文档生成的步骤,而具体的文档格式和内容由子类负责实现。这样可以实现同一套生成流程适应不同类型或格式的文档。
-
算法设计: 当有一个算法的基本结构是固定的,但某些具体步骤可能因应用场景而变化时,可以使用模板方法。例如,排序算法中的比较和交换可以是通用步骤,而具体的比较策略可以在子类中实现。
-
生命周期管理: 在对象的生命周期管理中,模板方法常常用于定义对象的创建、初始化、销毁等生命周期步骤。具体的对象创建方式或初始化细节可以由子类实现,以满足不同的需求。
-
日常工作流程: 在业务流程中,例如审批流程、报销流程等,可以使用模板方法模式定义通用的流程步骤,而具体的审批条件或报销条款可以由子类进行实现。这样可以确保整个流程的一致性,同时灵活应对不同的业务需求。