目的
固定一个操作算法的骨架,只允许子类重写实现细节,无法更改执行步骤。
定义
一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。
结构
demo
不适用钩子
抽象模板
public abstract class Beverage {
final void getBeverage() {
boilingWater();
make();
pour();
addFlavoring();
}
public void boilingWater() {
System.out.println("烧水。。。");
}
public abstract void make();
public void pour() {
System.out.println("倒入杯中。。。。");
}
public abstract void addFlavoring();
}
具体模板
public class Tea extends Beverage {
@Override
public void make() {
System.out.println("把水倒入放有茶叶的杯中,盖上盖子");
}
@Override
public void addFlavoring() {
System.out.println("放入几片柠檬");
}
}
public class Coffee extends Beverage {
@Override
public void make() {
System.out.println("将水倒入装有coffee的杯中不断搅拌");
}
@Override
public void addFlavoring() {
System.out.println("加入 牛奶和糖");
}
}
如上所示茶和coffee都是饮料,抽象模板中定义了制作饮料的具体步骤,并且将共同的实现步骤boilingWater和pour抽取到自身提高代码复用,而各种饮料特有的make和addFlavoring交由具体类自身选择实现。
使用钩子
抽象模板
public abstract class Beverage {
final void getBeverage() {
boilingWater();
make();
pour();
addFlavoring();
}
public void boilingWater() {
System.out.println("烧水。。。");
}
public abstract void make();
public void pour() {
if (pourPlace()) {
System.out.println("倒入杯中。。。。");
}
}
public abstract void addFlavoring();
public boolean pourPlace() {
return true;
}
}
具体模板
public class Tea extends Beverage {
@Override
public void make() {
System.out.println("把水倒入放有茶叶的杯中,盖上盖子");
}
@Override
public void addFlavoring() {
System.out.println("放入几片柠檬");
}
}
public class Coffee extends Beverage {
@Override
public void make() {
System.out.println("将水倒入装有coffee的杯中不断搅拌");
}
@Override
public void addFlavoring() {
System.out.println("加入 牛奶和糖");
}
@Override
public boolean pourPlace() {
return false;
}
}
client
public class Client {
public static void main(String[] args) {
Beverage beverage = new Tea();
beverage.getBeverage();
beverage = new Coffee();
beverage.getBeverage();
}
}
优点
约定算法执行步骤,提高代码复用性与扩展性,实现了反向控制
缺点
引入抽象类,每一个不同的操作都需要具体子类实现,可能会出现类爆炸。。
使用时机
- 需要控制算法执行步骤
- 自身实现部分通用,可变的交由子类自身实现
- 控制子类的扩展