模板方法模式是一种行为设计模式,在超类中定义了一个算法的框架,而将一些步骤的实现延迟到子类中,使得子类可重定义该算法的特定步骤。
Template Method is a behavior design pattern. It defines an algorithm framework in the superclass,
but delays the implementation of some steps to subclasses, so that subclasses can redefine specific steps
of the algorithm.
结构设计
模板方法模式包含如下角色:
Abstract Class,抽象类,实现一个模板方法,定义了算法的骨架。需要说明的是,算法中的步骤可以被声明为抽象类型,也可以提供一些默认实现。
Concrete Class,具体类,按需实现算法步骤,但不能重写模板方法自身。
模板方法模式类图表示如下:
一个模板方法用一些抽象的操作定义一个算法,而子类将重定义这些操作以提供具体的行为。通过使用抽象操作定义一个算法的一些步骤,模板方法确定了它们的先后顺序,但允许子类改变这些具体步骤以满足它们各自的需求。
伪代码实现
接下来将使用代码介绍下模板方法模式的实现。
// 1、抽象类,实现一个模板方法,定义了算法的骨架
public abstract class AbstractClass {
// 将方法声明为final,表示该方法不可override
public final void templateMethod() {
operation1();
operation2();
}
protected abstract void operation1();
protected abstract void operation2();
}
//2、具体类,按需实现算法步骤
public class ConcreteClassA extends AbstractClass {
@Override
protected void operation1() {
System.out.println("operation1 in a ConcreteClassA instance");
}
@Override
protected void operation2() {
System.out.println("operation2 in a ConcreteClassA instance");
}
}
public class ConcreteClassB extends AbstractClass {
@Override
protected void operation1() {
System.out.println("operation1 in a ConcreteClassB instance");
}
@Override
protected void operation2() {
System.out.println("operation2 in a ConcreteClassB instance");
}
}
// 3、客户端
public class TemplateMethodClient {
public void test() {
// (1) 创建具体类示例
AbstractClass classA = new ConcreteClassA();
// (2) 调用模板方法
classA.templateMethod();
AbstractClass classB = new ConcreteClassB();
classB.templateMethod();
}
}
适用场景
在以下情况下可以考虑使用模板方法模式:
(1) 如果只希望子类扩展某个特定算法步骤,而不是整个算法或其结构时,可考虑使用模板方法模式。模板方法将整个算法转换为一系列独立的步骤,以便子类能对其进行扩展,同时还可让超类中所定义的结构保持完整。
(2) 当多个类的算法除一些细微不同之外几乎完全一样时, 可使用该模式。但其后果就是,只要算法发生变化,就可能需要修改所有的类。在将算法转换为模板方法时,可将相似的实现步骤提取到超类中以去除重复代码。子类间各不同的代码可继续保留在子类中。
优缺点
模板方法模式有以下优点:
(1) 仅允许子类重写算法中的特定部分,使得算法其他部分修改对其所造成的影响减小。
(2) 可将重复代码提取到父类中。
但是该模式也存在以下缺点:
(1) 部分子类可能会受到算法框架的限制。如果算法框架需要调整,则该模式不适用。
(2) 通过子类抑制默认步骤实现可能会导致违反里氏替换原则。
(3) 每一个不同的实现都需要一个子类实现,导致类的个数增加,使得系统更加庞大。模板方法中的步骤越多, 其维护工作就可能会越困难。
参考
《设计模式 可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著, 李英军, 马晓星等译
https://refactoringguru.cn/design-patterns/visitor 模板方法模式
https://www.runoob.com/design-pattern/visitor-pattern.html 模板方法模式
https://www.cnblogs.com/adamjwh/p/10968634.html 简说设计模式——模板方法模式