夜雨聆风学习资料网

ARTICLE · 1329476

模板方法模式详解:定义算法骨架,让子类自由实现具体步骤

模板方法模式详解:定义算法骨架,让子类自由实现具体步骤

在项目开发过程中,有些业务虽然整体执行流程相同,但是其中某些具体步骤的实现方式并不一样。如果把这些步骤全部重复实现,不仅代码容易冗余,后续维护起来也比较麻烦。

这时候,就可以使用模板方法模式。

模板方法模式通过定义一个固定的算法流程,将其中一些具体步骤交给子类实现,从而在保证整体流程不变的情况下,让不同子类拥有不同的具体实现。

本文按照你提供的内容,整理一下什么是模板方法模式,以及模板方法模式在 Java 中具体是如何实现的。

一、什么是模板方法模式?

模板方法模式(Template Method Pattern)是一种行为型设计模式。它定义了一个操作中的算法骨架,并将其中一些步骤延迟到子类中实现。

也就是说,模板方法模式会提前定义好整个算法的执行流程,而具体某些步骤到底怎么执行,则交给子类来决定。

它的核心思想可以概括为:整体流程固定,具体步骤由子类实现。

模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些特定步骤。例如,一个操作可能包含:

步骤一  ↓步骤二  ↓操作完成

模板方法可以把这个执行顺序固定下来:

templateMethod()      ↓   stepOne()      ↓   stepTwo()

具体的 stepOne() 和 stepTwo() 如何实现,则交给不同的子类。这样,不同子类可以拥有不同的步骤实现,但整个算法的执行顺序保持不变。

二、模板方法模式在 Spring 中的应用

在 Spring 框架中,也有很多模板方法的应用。例如:JdbcTemplate、RestTemplate这些模板类定义了数据访问的通用流程。使用的时候,我们只需要提供具体的:SQL、回调方法即可。

也就是说,通用的处理流程已经由模板定义好了,具体需要执行的内容由使用方提供。这种方式能够减少重复的流程代码,让我们更加关注具体业务内容。

三、模板方法模式在 Java 中具体怎么实现?

模板方法通常通过:抽象类 + 继承来实现。

抽象类负责定义模板方法。模板方法中包含一系列步骤,并规定这些步骤的调用顺序。而具体的步骤,则由子类负责实现。

整体结构可以理解为:

AbstractClass      │      │ 定义模板方法      ↓templateMethod()      │      ├── stepOne()      │      └── stepTwo()      ↓  ┌───────────────┐  ↓               ↓ConcreteClassA  ConcreteClassB  ↓               ↓实现 stepOne    实现 stepOne实现 stepTwo    实现 stepTwo

下面结合具体代码来看。

3.1 抽象类

首先定义一个抽象类 AbstractClass。

abstract class AbstractClass {    // 模板方法,定义算法的骨架    public final void templateMethod() {        stepOne();        stepTwo();    }    protected abstract void stepOne();    protected abstract void stepTwo();}

这里的 AbstractClass 就是模板方法模式中的抽象类。其中最核心的是:

public final void templateMethod()

这个方法就是模板方法。它定义了整个算法的执行骨架:

stepOne()   ↓stepTwo()

也就是说,无论后面是哪一个具体子类,都需要按照这个顺序执行。

3.2 模板方法

模板方法中定义了算法的执行顺序:

public final void templateMethod() {    stepOne();    stepTwo(;}

这里首先执行:stepOne();,然后执行:stepTwo();,因此,模板方法实际上负责的是:定义流程,而不是定义每一个步骤的具体实现。而具体步骤:

protected abstract void stepOne();protected abstract void stepTwo();

则定义成抽象方法,由子类去实现。

3.3 具体子类

定义好抽象类之后,就可以创建具体的子类。首先是 ConcreteClassA:

class ConcreteClassA extends AbstractClass {    @Override    protected void stepOne() {        System.out.println("ConcreteClassA: Step One");    }    @Override    protected void stepTwo() {        System.out.println("ConcreteClassA: Step Two");    }}

ConcreteClassA 继承 AbstractClass,然后实现:

stepOne()stepTwo()

两个具体步骤。

接下来是 ConcreteClassB:

class ConcreteClassB extends AbstractClass {    @Override    protected void stepOne() {        System.out.println("ConcreteClassB: Step One");    }    @Override    protected void stepTwo() {        System.out.println("ConcreteClassB: Step Two");    }}

同样,ConcreteClassB 也实现了:

stepOne()stepTwo()

不过,它们的具体实现内容可以不同。因此:

AbstractClass      ↓固定执行流程      ↓stepOne → stepTwo      ↓┌──────────────┐│              │↓              ↓A              B↓              ↓具体实现       具体实现

整个流程由父类控制,而具体步骤由子类实现。

3.4 客户端调用

最后,通过客户端代码来调用模板方法。

public class TemplateMethodPatternDemo {    public static void main(String[] args) {        AbstractClass classA = new ConcreteClassA();        classA.templateMethod();        AbstractClass classB = new ConcreteClassB();        classB.templateMethod();    }}

首先创建:

AbstractClass classA = new ConcreteClassA();

然后调用:

classA.templateMethod();

虽然调用的是父类定义的模板方法:

templateMethod()

但是在执行:

stepOne();stepTwo();

时,会执行 ConcreteClassA 中具体实现的方法。

接下来创建:

AbstractClass classB = new ConcreteClassB();

再调用:

classB.templateMethod();

这一次执行的就是 ConcreteClassB 中对应的具体步骤。

四、模板方法模式的整体执行流程

将上面的代码串起来,整个模板方法模式的执行过程就是:

客户端  ↓AbstractClass  ↓templateMethod()  ↓stepOne()  ↓stepTwo()  ↓具体子类实现

对于 ConcreteClassA:

templateMethod()      ↓ConcreteClassA.stepOne()      ↓ConcreteClassA.stepTwo()

对于 ConcreteClassB:

templateMethod()      ↓ConcreteClassB.stepOne()      ↓ConcreteClassB.stepTwo()

可以看到,虽然两个具体子类的实现不同,但是它们执行的整体流程是一致的。

也就是:父类负责定义算法骨架,子类负责实现具体步骤。

五、总结

模板方法模式是一种行为型设计模式,它的核心就是:定义算法骨架,将部分步骤延迟到子类实现。

在 Java 中,模板方法通常通过:

抽象类  ↓模板方法  ↓定义固定执行顺序  ↓抽象步骤  ↓具体子类实现

来完成。

其中:

  • 抽象类
    :定义整体算法结构
  • 模板方法
    :定义具体步骤的执行顺序
  • 抽象方法
    :定义需要子类实现的步骤
  • 具体子类
    :实现具体步骤

在 Spring 中,也存在模板方法的应用,例如 JdbcTemplate、RestTemplate,它们定义了通用的处理流程,我们只需要提供具体的 SQL 或者回调方法。

所以,遇到整体流程固定,但是其中某些步骤需要根据具体实现进行变化的场景,就可以考虑使用模板方法模式。

六、写在最后

设计模式并不是为了把简单代码写复杂,而是为了在面对不同业务场景时,有更加合适的代码组织方式。

模板方法模式的核心其实就一句话:流程我来定,细节你来实现。

如果这篇文章对你有帮助,欢迎点个赞 👍、收藏 ⭐、点个“在看” 👀。

你的每一次点赞、收藏和在看,都是我持续整理 Java、设计模式、微服务 技术干货的动力!

一起学习,一起进步,下篇继续!

回首页,搜索你想要的文档

在首页搜索框输入关键词,快速定位资料

文库首页搜索指引 立即搜索

相关学习资料