模板方法模式(Template Method Pattern)是一种行为型设计模式,它通过一个抽象类定义了一个操作的算法骨架,而将一些步骤延迟到子类中实现。
简而言之,模板方法模式就像是一个烹饪食谱,规定了基本的烹饪流程(算法骨架),但允许厨师根据具体食材(子类)调整某些步骤(如烹饪时间、温度等),从而制作出不同风味的菜肴。
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.
定义一个操作中的算法框架,进而推迟一些步骤的执行,将其延迟到子类中。模板方法使得子类在不改变算法的结构的情况下,可以改变算法的某些特定步骤。
模板方法模式从字面上理解,可以拆分为“模板”和“方法”两个部分。
我们可以以一个简单的烹饪过程为例。假设我们有一个基本的烹饪流程,其中包含了预热烤箱、烹饪食物和关闭烤箱的步骤。但不同的食物需要不同的烹饪时间和温度,这部分就是可以定制的部分。
假设我们想要烤一个蛋糕和一个披萨。两者都需要预热烤箱,但烹饪时间和温度不同,烹饪完成后都需要关闭烤箱。这里,预热烤箱和关闭烤箱就是模板方法中固定的部分,而烹饪食物则是需要根据不同食物来定制的部分。(见下文示例解析)
模板方法模式(Template Method Pattern)中的角色通常包括:
通过使用模板方法模式,开发者可以在不改变算法结构的情况下,通过子类来重定义算法的某些特定步骤,从而实现算法的灵活性和可复用性。
下面是一个Java示例,展示了模板方法模式:
package com.polaris.designpattern.list3.behavioral.pattern01.templatemethod.classicdemo;
// 抽象类,定义了模板方法
abstract class AbstractClass {
// 模板方法,定义了算法的框架
public final void templateMethod() {
specificMethod1(); // 调用第一个抽象方法
// 可能还有其他的通用操作或条件判断
specificMethod2(); // 调用第二个抽象方法
}
// 抽象操作,子类必须实现
protected abstract void specificMethod1();
// 另一个抽象操作,子类也必须实现
protected abstract void specificMethod2();
}
// 具体子类A
class ConcreteClassA extends AbstractClass {
// 实现抽象操作
@Override
protected void specificMethod1() {
System.out.println("ConcreteClassA.specificMethod1()");
}
// 实现抽象操作
@Override
protected void specificMethod2() {
System.out.println("ConcreteClassA.specificMethod2()");
}
}
// 具体子类B
class ConcreteClassB extends AbstractClass {
// 实现抽象操作
@Override
protected void specificMethod1() {
System.out.println("ConcreteClassB.specificMethod1()");
}
// 实现抽象操作
@Override
protected void specificMethod2() {
System.out.println("ConcreteClassB.specificMethod2()");
}
}
// 客户端代码
public class TemplateMethodTest {
public static void main(String[] args) {
AbstractClass classA = new ConcreteClassA();
classA.templateMethod(); // 输出 ConcreteClassA.specificMethod1() 和 ConcreteClassA.specificMethod2()
AbstractClass classB = new ConcreteClassB();
classB.templateMethod(); // 输出 ConcreteClassB.specificMethod1() 和 ConcreteClassB.specificMethod2()
}
}
/* Output:
ConcreteClassA.specificMethod1()
ConcreteClassA.specificMethod2()
ConcreteClassB.specificMethod1()
ConcreteClassB.specificMethod2()
*///~
在这个示例中,
AbstractClass
是抽象类,它定义了一个模板方法templateMethod()
,该方法调用了两个抽象操作specificMethod1()
和specificMethod2()
。ConcreteClassA
和ConcreteClassB
是具体子类,它们分别实现了这两个抽象操作。客户端代码通过调用模板方法来执行算法,而具体的步骤(specificMethod1()
和specificMethod2()
)则由不同的子类实现。
模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个操作中的算法框架,而将一些步骤延迟到子类中。这使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
模板方法模式在以下场景中特别有用:
模板方法模式是一种非常实用的设计模式,它可以帮助我们更好地组织代码,提高代码的可维护性和可扩展性。
假设我们有一个基本的烹饪流程,其中包含了预热烤箱、烹饪食物和关闭烤箱的步骤。但不同的食物需要不同的烹饪时间和温度,这部分就是可以定制的部分。
假设我们想要烤一个蛋糕和一个披萨。两者都需要预热烤箱,但烹饪时间和温度不同,烹饪完成后都需要关闭烤箱。这里,预热烤箱和关闭烤箱就是模板方法中固定的部分,而烹饪食物则是需要根据不同食物来定制的部分。
package com.polaris.designpattern.list3.behavioral.pattern01.templatemethod.cookingdemo;
// 抽象类,代表烹饪流程
abstract class CookingProcess {
// 模板方法,定义了烹饪的整个过程
public final void cook() {
preheatOven(); // 预热烤箱
cookFood(); // 烹饪食物(需要子类实现)
turnOffOven(); // 关闭烤箱
}
// 预热烤箱的具体方法,不需要子类改变
protected void preheatOven() {
System.out.println("Preheating oven to 350°F...");
// 假设预热完成需要一些时间,这里省略等待逻辑
}
// 烹饪食物的方法,需要子类实现
protected abstract void cookFood();
// 关闭烤箱的具体方法,不需要子类改变
protected void turnOffOven() {
System.out.println("Turning off the oven...");
}
}
// 蛋糕烹饪类
class CakeCooking extends CookingProcess {
// 实现烹饪食物的方法,这里是烹饪蛋糕
@Override
protected void cookFood() {
System.out.println("Baking cake for 30 minutes...");
// 假设烹饪完成需要一些时间,这里省略等待逻辑
}
}
// 披萨烹饪类
class PizzaCooking extends CookingProcess {
// 实现烹饪食物的方法,这里是烹饪披萨
@Override
protected void cookFood() {
System.out.println("Baking pizza for 15 minutes at 450°F...");
// 假设烹饪完成需要一些时间,这里省略等待逻辑
}
}
// 客户端代码
public class CookingDemo {
public static void main(String[] args) {
CookingProcess cakeCooking = new CakeCooking();
cakeCooking.cook(); // 烹饪蛋糕
System.out.println("--------------------");
CookingProcess pizzaCooking = new PizzaCooking();
pizzaCooking.cook(); // 烹饪披萨
}
}
/* Output:
Preheating oven to 350°F...
Baking cake for 30 minutes...
Turning off the oven...
--------------------
Preheating oven to 350°F...
Baking pizza for 15 minutes at 450°F...
Turning off the oven...
*///~
这个例子展示了模板方法模式如何帮助我们在保持烹饪流程基本框架不变的情况下,为不同的食物定制不同的烹饪步骤。