1 基本介绍
模板方法模式(Template Method Pattern)又叫做模板模式(Template Pattern)、模板方法模式在一个抽象类中公开定义了执行它的方法模板,它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。简单来说,模板方法模式就是定义一个操作中的算法骨架,将一些步骤延迟到子类中,使得子类可以在不改变一个算法结构的前提下重新定义该算法的某些特定步骤。
角色分析:
1)AbstractClass抽象类:该类中实现了模板方法template(通常是final的),定义了算法骨架,具体子类需要去实现其他的抽象方法operation1、operation2、operation3。
2)ImplementClass1、ImplementClass2:继承自AbstractClass,实现乐抽象方法operation1、operation2、operation3,以完成算法中特定的步骤。
2 模板方法模式举例
以制作奶茶为例,制作奶茶的步骤通常如下:
1)烧水,5分钟
2)加入奶茶粉
3)添加调味品(牛奶或咖啡)
4)添加果肉
上面四个步骤中第3步和第4步是可以通过个人喜好加入不同调料的,所以我们可以用模板方法来实现这个需求。
首先有一个奶茶的基类MilkTea:
public abstract class MilkTea {
public final void makeMilkTea() {
boilingWater();
addPowder();
addFlavouring();
addFruit();
}
void boilingWater() {
System.out.println("烧水,5分钟");
}
void addPowder() {
System.out.println("加入奶茶粉");
}
abstract void addFlavouring();
abstract void addFruit();
}
椰子牛奶奶茶继承MilkTea:
public class CoconutMilkTea extends MilkTea {
@Override
void addFlavouring() {
System.out.println("添加牛奶");
}
@Override
void addFruit() {
System.out.println("添加椰子");
}
}
芒果咖啡奶茶也继承了MilkTea:
public class MangoCoffeeMilkTea extends MilkTea {
@Override
void addFlavouring() {
System.out.println("添加咖啡");
}
@Override
void addFruit() {
System.out.println("添加芒果");
}
}
Client端调用奶茶类来制作奶茶:
public class Client {
public static void main(String[] args) {
System.out.println("------制作一杯椰子牛奶奶茶------");
MilkTea coconutMilkTea = new CoconutMilkTea();
coconutMilkTea.makeMilkTea();
System.out.println("------制作一杯芒果咖啡奶茶------");
MilkTea mangoCoffeeMilkTea = new MangoCoffeeMilkTea();
mangoCoffeeMilkTea.makeMilkTea();
}
}
输出结果:
------制作一杯椰子牛奶奶茶------
烧水,5分钟
加入奶茶粉
添加牛奶
添加椰子
------制作一杯芒果咖啡奶茶------
烧水,5分钟
加入奶茶粉
添加咖啡
添加芒果
3 总结
模板方法模式用的还是比较广泛的,在各种框架中都或多或少用到过。像Android中的四大组件,Spring中的IOC容器。总结一下,模板方法模式有如下特点:
1)算法只存在一个地方,就是在基类中,容易修改,父类修改后子类自动继承。
2)实现了代码最大化复用,即父类的模板方法和已实现的某些步骤会被子类继承而直接使用。
3)既统一了算法,也提供了很大的灵活性。父类的模板方法确保了算法的结构保持不变,同时由子类提供部分步骤的实现。
4)每一个不同的实现都需要新建一个子类,导致类的数量增加,使系统更加庞大。
5)模板方法模式的使用场景:当要完成的某个过程需要执行一系列步骤,并且这一系列步骤基本相同,只是少数步骤实现可能不同,通常可以考虑用模板方法模式。