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、设计模式、微服务 技术干货的动力!
一起学习,一起进步,下篇继续!















































































