模板方法模式(Template Method Pattern)是行为设计模式的一种,它定义了一个操作中的算法骨架,而将某些步骤延迟到子类中实现。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤,从而使得代码复用和扩展性得到提升。
模式结构
- 抽象类(Abstract Class):它定义了一个或多个抽象操作,以及一个模板方法。这个模板方法定义了算法的骨架,按特定顺序调用抽象操作。
- 具体子类(Concrete Class):实现父类所定义的一个或多个抽象操作,没有抽象方法的存在,它们代表了具体的实现。
关键角色
- Template Method(模板方法):在抽象类中定义,用于定义一个操作中的算法骨架。该方法通常会调用一些抽象操作,这些抽象操作需要在具体子类中实现。
- Abstract Operation(抽象操作):在抽象类中声明,但不提供具体实现的操作。子类必须提供具体实现。
- Concrete Class(具体类):实现抽象类中的抽象操作,从而完成算法中与特定实现相关的步骤。
适用场景
- 当多个类有相似的操作,但是这些操作中的一些步骤可能在每个类中有不同的实现时。
- 需要控制子类的扩展,确保子类以特定方式执行某些操作,同时允许子类对这些操作进行定制。
优点
- 封装不变部分:将相同部分的代码放在抽象类中,减少代码重复。
- 提高代码复用:通过继承,子类可以重用抽象类的代码。
- 行为定制化:子类可以覆盖某些方法来实现特定的行为,增加了灵活性。
- 易于扩展:增加新的具体子类时,无需修改原有代码,符合开闭原则。
实现示例
假设我们要实现一个计算不同形状面积的框架,其中计算面积的基本步骤相似(比如都需要输出计算开始和结束的信息),但计算逻辑各不相同。
java
// 抽象类 Shape,定义模板方法 calculateArea()
abstract class Shape {
public final void calculateArea() { // final 方法不允许子类覆盖
System.out.println("Starting to calculate area...");
double area = doCalculateArea(); // 调用抽象操作
System.out.println("The area is: " + area);
System.out.println("Finished calculating area.");
}
// 抽象操作,留给子类实现
protected abstract double doCalculateArea();
}
// 具体子类 Circle
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
protected double doCalculateArea() {
return Math.PI * radius * radius;
}
}
// 具体子类 Rectangle
class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
protected double doCalculateArea() {
return width * height;
}
}
// 客户端代码
public class TemplateMethodDemo {
public static void main(String[] args) {
Shape circle = new Circle(5);
Shape rectangle = new Rectangle(4, 6);
circle.calculateArea();
rectangle.calculateArea();
}
}
在这个例子中,Shape
类定义了计算面积的模板方法calculateArea()
,其中调用了抽象操作doCalculateArea()
。Circle
和Rectangle
类作为具体子类,实现了doCalculateArea()
方法,提供了各自计算面积的逻辑。这样,我们既保证了计算流程的一致性,又允许子类灵活地定义其核心计算逻辑。