父类定义方法的前置和后置处理,子类只需要去实现具体的方法逻辑即可
父类为抽象类或普通类,模版方法用final修饰,不用子类去覆盖
- 应用场景:不同的业务流程中,只有其中一个步骤不同,其他都相同的场景
1. Demo
package com.design.pattern.day01;
public class Demo05 {
public static void main(String[] args) {
CoffeeMaker americanoCoffeeMaker = new AmericanoCoffeeMaker();
americanoCoffeeMaker.makeCoffee();
System.out.println("==============");
CoffeeMaker latteCoffeeMaker = new LatteCoffeeMaker();
latteCoffeeMaker.makeCoffee();
System.out.println("==============");
CoffeeMaker espresso = new CoffeeMaker() {
@Override
public void prepareCup() {
System.out.println("espresso coffee cup ready");
}
@Override
public void addCoffeeBean() {
System.out.println("espresso coffee cup ready");
}
};
espresso.makeCoffee();
}
}
class LatteCoffeeMaker extends CoffeeMaker {
@Override
public void prepareCup() {
System.out.println("latte coffee cup ready");
}
@Override
public void addCoffeeBean() {
System.out.println("latte coffee bean ready");
}
}
class AmericanoCoffeeMaker extends CoffeeMaker {
@Override
public void prepareCup() {
System.out.println("americano coffee cup ready");
}
@Override
public void addCoffeeBean() {
System.out.println("americano coffee bean ready");
}
}
abstract class CoffeeMaker {
/**
* 模版方法
* 1. 程序结构由父类控制; 可以做一些前处理及后处理
* 2. final 不允许被重写
* 3. 具体的业务逻辑由子类来实现
*/
public final void makeCoffee() {
prepareCup();
addWater();
addCoffeeBean();
}
// 确定的方法自己实现
private void addWater() {
System.out.println("add water");
}
// 不确定的方法子类实现
public abstract void prepareCup();
public abstract void addCoffeeBean();
}
2. 钩子函数
abstract class CoffeeMaker {
/**
* 模版方法
* 1. 程序结构由父类控制; 可以做一些前处理及后处理
* 2. final 不允许被重写
* 3. 具体的业务逻辑由子类来实现
*/
public final void makeCoffee() {
prepareCup();
addWater();
addCoffeeBean();
if (isSoldOut()) {
soldOutWarning();
}
}
// 确定的方法自己实现
private void addWater() {
System.out.println("add water");
}
// 不确定的方法子类实现
public abstract void prepareCup();
public abstract void addCoffeeBean();
// 钩子函数: 子类具体去实现具体的值
public abstract boolean isSoldOut();
public void soldOutWarning() {
System.out.println("this kind of coffee sold out");
}
}