代码文件目录:
CaffeineBeverage
package Chapter8_TemplateMethodPattern;
/**
* @Author 竹心
* @Date 2023/8/17
**/
public abstract class CaffeineBeverage {
final void prepareRecipe(){
boilWater();
brew();
pourInCup();
//这里使用钩子customerWantsCondiments()来让子类在算法过程中介入
if(customerWantsCondiments()){
addCondiments();
}
}
abstract void brew();//冲泡
abstract void addCondiments();//添加配料
void boilWater(){
//如果不想子类更改这些方法的实现,可以使用final
System.out.println("Boiling Water!");
}
void pourInCup(){
System.out.println("Pouring into cup");
}
//添加挂钩
boolean customerWantsCondiments(){
return true;
}
}
Coffee
package Chapter8_TemplateMethodPattern;
/**
* @Author 竹心
* @Date 2023/8/17
**/
public class Coffee extends CaffeineBeverage{
public void brew() {
System.out.println("Dripping Coffee through filter!");
}
public void addCondiments(){
System.out.println("Adding Sugar and Milk!");
}
public boolean customerWantsCondiments(){
//这里实行相关代码决定客户是否需要添加配料
return true;
}
}
Tea
package Chapter8_TemplateMethodPattern;
/**
* @Author 竹心
* @Date 2023/8/17
**/
public class Tea extends CaffeineBeverage{
public void brew(){
System.out.println("Steeping the tea!");
}
public void addCondiments(){
System.out.println("Adding Lemon!");
}
public boolean customerWantsCondiments(){
//这里实行相关代码决定客户是否需要添加配料
return true;
}
}
notes
模板方法模式
案例:
咖啡和茶这两种饮料的制作方法如下:
1.把水煮沸
2.把咖啡粉末(茶叶)加入水中
3.把咖啡(茶)倒进杯子
4.添加配料(柠檬、糖、奶等)
其中只有第2、4步是有所不同的(但也仅仅是涉及的对象不同),所以将四个步骤
抽取出来作为父类CaffeineBeverage中的方法,然后在父类中实现1、3两个步骤,
而2、4则由其子类(Tea, Coffee)来实现
模板方法:定义一个算法步骤,允许子类提供一个或者多个步骤的实现。
优点:
1.提高代码复用
2.可以在不改变算法结构的情况下,重新定义算法中的某些步骤,可维护性好(用案例来说,
就是如果要添加新的饮料,可以直接继承该父类,实现其独特的原料配方即可)
好莱坞原则:
高层组件主动决定控制底层组件,但是底层组件绝对不能调用高层组件。
模板方法模式(还有工厂模式、观察者模式)采用了这一原则
模板方法模式的应用:
常用的Arrays.sort()方法就涉及到模板方法模式,sort()可以对所有的对象数组
进行排序,前提是该数组的对象类型实行了接口Comparable下的compareTo()
方法。这里的sort()就是模板方法中的模板(遵循了模板方法模式的原则)。