特点:在一个方法中定义一个算法的骨架(如冲泡饮料流程),而将一些步骤延迟到子类中实现。
优点:模板模式可以使得子类在不改变核心算法的基础上,具体实现算法中的某些步骤。
例子:星巴克冲咖啡、泡茶
问题:咖啡与茶在制作过程中,烧水与倒入杯中这两个过程是重复操作。—>将这两个方法提取出来放在基类中,让咖啡和茶都继承此父类。
模板类的组成:
1.final修饰的核心算法
2.abstract修饰的抽象方法,延迟到子类实现
3.普通具体方法,所有子类都一样,子类直接使用即可
4.钩子方法 hook( ) --默认不做事的方法,子类可以视情况而定是否需要覆写
下面来看一个星巴克冲泡咖啡和茶的例子:
import java.util.Scanner;
abstract class AllCup{
final void print(){
boilWater();
putCailiao();
pourCup();
if(customerWant()){
addCailiao();
}
}
public void boilWater(){
System.out.println("将水烧开");
}
public void pourCup(){
System.out.println("将饮料倒入杯中");
}
abstract void putCailiao();
abstract void addCailiao();
boolean customerWant(){
return true;
}
}
class Caffe extends AllCup{
public void putCailiao(){
System.out.println("将咖啡放入杯中");
}
public void addCailiao(){
System.out.println("加入牛奶和糖");
}
}
class Tea extends AllCup{
public void putCailiao(){
System.out.println("将茶叶放入杯中");
}
public void addCailiao(){
System.out.println("加入柠檬片");
}
public boolean customerWant(){
String answer = getAnswer();
if(answer.equals("y")){
return true;
}
else{
return false;
}
}
private String getAnswer(){
String answer = null;
System.out.println("你想要加入柠檬吗?y表示愿意");
//在调用Scanner时,注意首行要声明
Scanner scanner = new Scanner(System.in);
//注意nextLine中的L的大写
answer = scanner.nextLine();
return answer;
}
}
public class Ex{
public static void main(String[] args){
AllCup all = new Caffe();
all.print();
System.out.println("------------");
AllCup tea = new Tea();
tea.print();
}
}
输出结果:
学习感受:在学习模板设计模式的时候,要找出第三方,这样就能事半功倍了。利用好抽象类,利用好开闭原则–一个软件实体如类、接口等应该对扩展开放,对修改关闭。