概念:
模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。该模式通过在抽象类中定义一个模板方法来控制算法的流程,并使用具体方法来实现其中的某些步骤。
特点:
- 定义了一个算法的骨架,将一些步骤延迟到子类中实现。
- 模板方法在抽象类中被声明为final或者不可重写,以确保整个算法流程不被修改。
- 具体步骤可以由子类进行扩展和重写。
优点:
- 提供了代码复用和扩展性,在父类中定义通用逻辑,而将具体实现细节交给子类。
- 简化代码结构,避免冗余代码。
缺点:
- 可能会导致继承滥用问题,因为父类对于子类有较高的耦合性。
- 由于部分逻辑是固定在父类中的,在需要改变这部分逻辑时可能需要修改整个继承链结构。
适用场景:
- 当多个相关对象有相同操作流程但各自具有不同实现时可以使用模板方法模式。
- 当希望通过固定的算法流程来控制子类的行为时可以使用模板方法模式。
实现方式:
- 抽象父类中定义一个模板方法,并在其中调用多个抽象方法,子类必须实现这些抽象方法。
- 在具体步骤中,如果有需要可选的操作,可以通过钩子方法来控制是否执行该操作。
- 子类继承父类并实现其中的抽象方法和钩子方法。
实现代码:
// 抽象父类
abstract class AbstractClass {
public final void templateMethod() {
// 步骤1
operation1();
// 步骤2
operation2();
// 钩子方法判断是否执行步骤3
if (hook()) {
// 步骤3(可选)
operation3();
}
}
protected abstract void operation1(); // 抽象方法
protected abstract void operation2(); // 抽象方法
protected void operation3() { // 可选的具体实现
// 具体步骤3的代码逻辑
System.out.println("可选的具体实现操作3");
}
protected boolean hook() { // 钩子方法,默认返回true,表示执行步骤3;可由子类重写以决定是否执行该步骤
return true;
}
}
// 具体子类A
class ConcreteClassA extends AbstractClass {
protected void operation1() {
System.out.println("具体子类A的操作1");
}
protected void operation2() {
System.out.println("具体子类A的操作2");
}
}
// 具体子类B
class ConcreteClassB extends AbstractClass {
protected void operation1() {
System.out.println("具体子类B的操作1");
}
protected void operation2() {
System.out.println("具体子类B的操作2");
}
protected boolean hook() {
return false; // 子类B重写钩子方法,不执行步骤3
}
}
public class Main {
public static void main(String[] args) {
// 使用示例
AbstractClass classA = new ConcreteClassA();
classA.templateMethod();
AbstractClass classB = new ConcreteClassB();
classB.templateMethod();
}
}
在上述示例中,我们定义了一个抽象父类 AbstractClass
,其中包含一个模板方法 templateMethod()
和多个抽象和具体方法。
在模板方法中,按照固定顺序调用了抽象方法 operation1()
和 operation2()
。同时,在步骤3之前增加了一个钩子方法 hook()
来决定是否执行该步骤。
然后,我们创建了两个具体子类 ConcreteClassA
和 ConcreteClassB
分别继承自抽象父类,并实现其中的抽象方法和钩子方法。
最后,在客户端代码中,我们可以通过创建不同的具体子类对象来调用模板方法。根据每个具体子类实现不同的逻辑,模板方法会按照预定义流程执行相应的操作。