前言
通过模板方法模式,我们可以方便地扩展和修改算法,同时保持算法结构的稳定性。这种模式常见于需要在算法中留有一些灵活性,让子类根据具体需求来实现的场景。
1.概念
模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤的具体实现延迟到子类。模板方法使得子类可以在不改变算法结构的情况下重新定义算法中的某些步骤。
模板类(Abstract Class): 定义一个算法的骨架,将算法的某些步骤延迟到子类实现。通常包含一个模板方法和若干抽象方法。
具体子类(Concrete Class): 实现模板类中的抽象方法,以完成算法中的具体步骤。
2.基本用法
- 定义一个抽象类作为模板类,里面定义若干抽象方法
- 具体实现类继承模板类,并写出具体方法实现
3.代码示例
下面是一个制作咖啡的场景,其中咖啡的制作步骤包含冲泡、加糖、加牛奶。我们可以使用模板方法模式来定义一个制作咖啡的算法骨架。
示例中,CoffeeTemplate 是模板类,定义了制作咖啡的算法骨架。makeCoffee 方法是模板方法,包含了制作咖啡的一系列步骤。具体的步骤由抽象方法(boilWater、brewCoffeeGrinds、pourInCup、addCondiments)延迟到具体子类(CoffeeA、CoffeeB)中实现。
// 模板类
public abstract class CoffeeTemplate {
// 模板方法,定义咖啡的制作步骤
public final void makeCoffee() {
boilWater();
brewCoffeeGrinds();
pourInCup();
addCondiments();
}
// 抽象方法,由子类实现
protected abstract void boilWater();
protected abstract void brewCoffeeGrinds();
protected abstract void pourInCup();
protected abstract void addCondiments();
}
// 具体子类 - 咖啡A
public class CoffeeA extends CoffeeTemplate {
protected void boilWater() {
System.out.println("Boiling water for Coffee A");
}
protected void brewCoffeeGrinds() {
System.out.println("Brewing coffee grinds for Coffee A");
}
protected void pourInCup() {
System.out.println("Pouring coffee into cup for Coffee A");
}
protected void addCondiments() {
System.out.println("Adding sugar and milk for Coffee A");
}
}
// 具体子类 - 咖啡B
public class CoffeeB extends CoffeeTemplate {
protected void boilWater() {
System.out.println("Boiling water for Coffee B");
}
protected void brewCoffeeGrinds() {
System.out.println("Brewing coffee grinds for Coffee B");
}
protected void pourInCup() {
System.out.println("Pouring coffee into cup for Coffee B");
}
protected void addCondiments() {
System.out.println("Adding honey for Coffee B");
}
}
// 客户端使用
public class Client {
public static void main(String[] args) {
CoffeeTemplate coffeeA = new CoffeeA();
coffeeA.makeCoffee();
System.out.println("----------------------");
CoffeeTemplate coffeeB = new CoffeeB();
coffeeB.makeCoffee();
}
}
4.总结
如果程序的框架已经确定,但某些步骤的具体实现可能不同时,使用 模板方法模式是一个好的选择,同时模板方法模式可以降低代码重复率,增强系统的可扩展性,避免代码冗余,提高代码一致性等作用。
当然模板方法模式并不适合所有场景,它也会导致类的熟练增加、继承关系局限性、系统复杂度增加等问题。使用时具体场景具体分析。