模板方法模式是一种行为设计模式,它定义了一个操作中的算法框架,将一些步骤延迟到子类中实现。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
结构
- 抽象类(Abstract Class): 定义了一个算法的骨架,包含一个或多个抽象方法,由子类实现。
public abstract class AbstractClass {
public void templateMethod() {
step1();
step2();
step3();
}
protected abstract void step1();
protected abstract void step2();
protected abstract void step3();
}
- 具体子类(Concrete Class): 实现了抽象类中定义的抽象方法,完成算法中特定步骤的具体实现。
public class ConcreteClass extends AbstractClass {
protected void step1() {
System.out.println("Step 1");
}
protected void step2() {
System.out.println("Step 2");
}
protected void step3() {
System.out.println("Step 3");
}
}
优点和缺点
优点:
- 代码复用: 模板方法模式使得公共步骤在父类中实现,子类只需实现特定的步骤,提高了代码的复用性。
- 符合开闭原则: 可以通过增加新的子类来扩展和修改算法的行为,而不需要修改父类的代码。
- 封装性良好: 将算法的具体实现封装在子类中,使得客户端只需要关心高层的算法结构。
缺点:
- 限制子类的灵活性: 模板方法模式在一定程度上限制了子类的灵活性,因为子类必须遵循父类的算法结构。
- 增加了类的数量: 每个具体算法都需要一个具体子类来实现,可能会增加类的数量,使得系统更加庞大。
示例
以下是一个简单的模板方法模式的示例,表示制作咖啡和茶的过程。在这个示例中,prepareBeverage 方法是模板方法,定义了制作饮料的算法框架,boilWater、brew 和 pourInCup 是具体步骤,由子类实现。
// 抽象类
public abstract class BeverageTemplate {
public final void prepareBeverage() {
boilWater();
brew();
pourInCup();
addCondiments();
}
protected abstract void boilWater();
protected abstract void brew();
protected abstract void pourInCup();
protected abstract void addCondiments();
}
// 具体子类 - 制作咖啡
public class Coffee extends BeverageTemplate {
protected void boilWater() {
System.out.println("Boiling water");
}
protected void brew() {
System.out.println("Dripping coffee through filter");
}
protected void pourInCup() {
System.out.println("Pouring into cup");
}
protected void addCondiments() {
System.out.println("Adding sugar and milk");
}
}
// 具体子类 - 制作茶
public class Tea extends BeverageTemplate {
protected void boilWater() {
System.out.println("Boiling water");
}
protected void brew() {
System.out.println("Steeping the tea");
}
protected void pourInCup() {
System.out.println("Pouring into cup");
}
protected void addCondiments() {
System.out.println("Adding lemon");
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
BeverageTemplate coffee = new Coffee();
System.out.println("Making coffee:");
coffee.prepareBeverage();
System.out.println();
BeverageTemplate tea = new Tea();
System.out.println("Making tea:");
tea.prepareBeverage();
}
}
在这个例子中,prepareBeverage 方法定义了饮料制作的步骤,子类 Coffee 和 Tea 分别实现了父类的抽象方法,完成了咖啡和茶的制作过程。模板方法模式允许子类在不改变算法结构的情况下,重新定义算法的特定步骤,实现了算法的复用和扩展。