23 种设计模式中的模板模式
在父类中定义了算法的骨架,将某些步骤延迟到字类中,并允许子类在不改变算法结构的前提下重定义算法的某些特定步骤。
模板方法,主要的设计思想是,一个抽象的公开类定义了方法的框架。对于其中的一系列步骤,暂时确定不下来的步骤,就留给子类去实现好了。这样,不同的子类就可以定义不同的步骤。
这里我们根据案例来具体学习访问者模式。以下是一个代码示例及知识点详解。
假设我们要制作两种饮料:茶和咖啡。它们的制作过程有一些共同的步骤,但有一些步骤是不同的。我们可以使用模板方法来实现这个场景。
我们将创建一个定义操作的Beverage
类,其中,模板方法定义为 final
,这样它就不会被重写。Tea
和 Coffee
扩展了Beverage
,它们重写了抽象类的方法。
定义抽象类Beverage
。
abstract class Beverage {
// 模板方法,定义了制作饮料的算法框架
public final void prepareBeverage() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
// 具体步骤,子类必须实现
abstract void brew();
abstract void addCondiments();
// 具体步骤,子类可以选择覆盖
boolean customerWantsCondiments() {
return true;
}
// 具体步骤,通用方法
void boilWater() {
System.out.println("Boiling water");
}
void pourInCup() {
System.out.println("Pouring into cup");
}
}
定义实体类Tea
。
class Tea extends Beverage {
@Override
void brew() {
System.out.println("Steeping the tea");
}
@Override
void addCondiments() {
System.out.println("Adding lemon");
}
@Override
boolean customerWantsCondiments() {
// 假设用户不喜欢加柠檬
return false;
}
}
定义实体类Coffee
。
class Coffee extends Beverage {
@Override
void brew() {
System.out.println("Dripping coffee through filter");
}
@Override
void addCondiments() {
System.out.println("Adding sugar and milk");
}
}
使用模板方法。
public class TemplateMethodDemo {
public static void main(String[] args) {
Beverage tea = new Tea();
Beverage coffee = new Coffee();
System.out.println("Making tea...");
tea.prepareBeverage();
System.out.println("\nMaking coffee...");
coffee.prepareBeverage();
}
}
Beverage
类中的prepareBeverage()
方法是模板方法,它定义了制作饮料的算法框架。brew()
和addCondiments()
是抽象方法,子类必须实现这些方法以提供具体的步骤。customerWantsCondiments()
是一个钩子方法,子类可以选择覆盖它来改变算法的行为。boilWater()
和pourInCup()
是具体方法,它们在父类中实现,子类可以直接使用。
通过这种方式,模板方法模式允许我们在不改变算法结构的情况下,灵活地改变算法的某些步骤。
总结
模板方法是一种高层定义骨架,底层实现细节的设计模式,适用于流程固定,但某些步骤不确定或可替换的情况。