介绍
定义一个模版数据结构,将具体内容延迟到子类实习
在不改变模板结构的前提下在子类中重新定义模板中的内容。
模板方法模式是基于”继承“的;
1.解决的问题
- 提高代码复用性
将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中 - 实现了反向控制
通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 & 符合“开闭原则”
2.模式原理
3.使用实例来讲解
- 背景:苏粥粥希望学做奶茶:芋泥波波 & 珍珠奶茶
- 冲突:两道奶茶的放东西步骤有的重复有的却差异很大,记不住
- 解决方案:利用代码记录下来
public abstract class MilkyTea{
// 这里使用 final 保整子类不去修改此方法
final void MakeMilkVegetables(){
//第一步:倒奶
this.PourTheMilk();
//第二步:搅拌
this.stir();
//第三步:倒材料
this.materials();
//第四步:开始封口
this.packaging();
}
//第一步:倒奶是一样的,所以直接实现
void PourTheMilk(){
System.out.println("倒奶和茶");
}
//第二步:搅拌是一样的,所以直接实现
void stir(){
System.out.println("搅拌");
}
//第三步:倒材料是不一样的(一个下芋泥波波,一个是下珍珠)
//所以声明为抽象方法,具体由子类实现
abstract void materials();
//第五步:封口是一样的,所以直接实现
void packaging();{
System.out.println("开始封口,咔嚓咔嚓咔嚓");
}
}
// 制作芋泥波波的类
public class yunibobozhizuo extend MilkyTea {
@Override
public void materials(){
System.out.println("放入芋泥波波");
}
}
// 制作珍珠奶茶的类
public class zhenzunaicai extend MikyTea {
@Override
public void materials(){
System.out.println("放入珍珠");
}
}
public class Main {
public static void main(String[] args) {
// 使用制作芋泥波波奶茶
yunibobozhizuo yuni = new yunibobozhizuo();
yuni.MakeMilkVegetables();
}
}
结果输出:
倒奶和茶
搅拌
放入芋泥波波
开始封口,咔嚓咔嚓咔嚓
上面就是模版方法在代码里面使用案例.
4.优缺点
- 优点
- 提高代码复用性
将相同部分的代码放在抽象的父类中 - 提高了拓展性
将不同的代码放入不同的子类中,通过对子类的扩展增加新的行为 - 实现了反向控制
通过一个父类调用其子类的操作,通过对子类的扩展增加新的行为,实现了反向控制 & 符合“开闭原则”
- 提高代码复用性
- 缺点
- 引入了抽象方法,每一次使用此模版都需要创建一个新子类导致类的个数增加,从而增加了系统实现的复杂度。
应用场景
- 引入了抽象方法,每一次使用此模版都需要创建一个新子类导致类的个数增加,从而增加了系统实现的复杂度。
- 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现;
- 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复;
- 控制子类的扩展。