「全网最细 + 实战源码案例」设计模式——模板方法模式

简介: 模板方法模式是一种行为型设计模式,定义了算法的骨架并在父类中实现不变部分,将可变部分延迟到子类实现。通过这种方式,它避免了代码重复,提高了复用性和扩展性。具体步骤由抽象类定义,子类实现特定逻辑。适用于框架设计、工作流和相似算法结构的场景。优点包括代码复用和符合开闭原则,缺点是可能违反里氏替换原则且灵活性较低。

核心思想

  • 模板方法模式(Template Method Pattern)是一种行为型设计模式,定义了一个算法的骨架(模板),将某些步骤延迟到子类中实现(在不修改结构的情况下),以避免代码重复,提高代码复用性,保持算法的结构稳定。
  • 核心:
    • 模板方法:在父类中定义一个算法的骨架(即模板方法),其中包含一些抽象方法或钩子方法(hook methods),这些方法由子类实现。
    • 不变部分:算法的整体结构是固定的,由父类控制。
    • 可变部分:算法的某些步骤可以被子类重写,以实现不同的行为。

    image.png


结构

1. 抽象类(Abstract Class)

  • 定义算法的骨架(模板方法)。
  • 由一个模板方法和若干个基本方法构成。
    • 模板方法:定义算法骨架,按某种顺序调用其包含的基本方法。
    • 基本方法:实现算法各步骤的方法,是模板方法的组成部分,分为三类:
      • 抽象方法:由抽象类声明,具体子类实现。
      • 具体方法:一个具体方法由一个抽象类或具体类声明并实现,其子类可以覆盖或继承。
      • 钩子方法:抽象类中已实现,包括用于判断的逻辑方法和需要子类重写的空方法。

2. 具体子类(Concrete Class)

  • 实现抽象类中所定义的抽象方法或钩子方法,是一个顶级逻辑的组成步骤。

编辑


现实世界类比

  • 模板方法可用于建造大量房屋。 标准房屋建造方案中可提供几个扩展点, 允许潜在房屋业主调整成品房屋的部分细节。

编辑

  • 每个建造步骤 (例如打地基、 建造框架、 建造墙壁和安装水电管线等) 都能进行微调, 这使得成品房屋会略有不同。

适用场景

  1. 算法复用:当多个类有相似的算法结构,只有某些步骤不同时。
  2. 框架设计: 框架通常定义算法的股价,而将具体实现留给用户。如何 Spring 中的 JdbcTemplate定义了数据库操作的流程,用户只需实现具体的 SQL 语句。
  3. 工作流设计:定义固定的工作流程,但允许某些步骤自定义。

优缺点

优点:

  1. 代码复用:不变的部分放在子类,避免代码重复。
  2. 提高扩展性:子类通过实现抽象方法或重写钩子方法类扩展算法的某些步骤。
  3. 符合开闭原则: 算法整体结构(修改)是封闭的,但具体步骤(扩展)是开放的。

缺点:

  1. 一定程度违反里氏替换原则:子类重写默认步骤后可能无法替代父类。
  2. 缺乏灵活性(相比策略模式) :子类必须继承模板。

实现步骤

  1. 分析目标算法, 确定能否将其分解为多个步骤。 从所有子类的角度出发, 考虑哪些步骤能够通用, 哪些步骤各不相同。
  2. 创建抽象基类并声明一个模板方法和代表算法步骤的一系列抽象方法。 在模板方法中根据算法结构依次调用相应步骤。 可用 final最终修饰模板方法以防止子类对其进行重写。
  3. 虽然可将所有步骤全都设为抽象类型, 但默认实现可能会给部分步骤带来好处, 因为子类无需实现那些方法。
  4. 可考虑在算法的关键步骤之间添加钩子。
  5. 为每个算法变体新建一个具体子类, 它必须实现所有的抽象步骤, 也可以重写部分可选步骤。

示例

编辑

// 抽象类(定义模板方法和基本方法)
public abstract class AbstractClass {

    // 模板方法定义
    public final void cookProcess(){
        pourOil();
        heatOil();
        pourVegetable();
        pourSauce();
        fry();
    }

    public void pourOil(){
        System.out.println("倒油");
    }

    public void heatOil(){
        System.out.println("热油");
    }

    public abstract void pourVegetable();

    public abstract void pourSauce();

    public void fry(){
        System.out.println("翻炒");
    }
}

// 具体子类——包菜
public class BaoCai extends AbstractClass{
    @Override
    public void pourVegetable() {
        System.out.println("下锅的蔬菜是包菜");
    }

    @Override
    public void pourSauce() {
        System.out.println("下锅的酱料是辣椒");
    }
}

// 具体子类——菜心
public class CaiXin extends AbstractClass{
    @Override
    public void pourVegetable() {
        System.out.println("下锅的蔬菜是菜心");
    }

    @Override
    public void pourSauce() {
        System.out.println("下锅的酱料是蒜蓉");
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {

        AbstractClass baoCai = new BaoCai();
        baoCai.cookProcess();

        System.out.println("---------------------------------------------");

        AbstractClass caiXin = new CaiXin();
        caiXin.cookProcess();
    }
}


在源码中的应用

编辑

编辑


与其他模式的关系

  • 工厂方法模式模板方法模式的一种特殊形式。 同时, 可以作为一个大型 中的一个步骤。
  • 模板方法基于继承机制: 它允许你通过扩展子类中的部分内容来改变部分算法。 策略模式基于组合机制: 你可以通过对相应行为提供不同的策略来改变对象的部分行为。 模板方法在类层次上运作, 因此它是静态的。 策略在对象层次上运作, 因此允许在运行时切换行为。

目录
相关文章
|
14天前
|
设计模式 人工智能 算法
基于多设计模式的状态扭转设计:策略模式与责任链模式的实战应用
接下来,我会结合实战案例,聊聊如何用「策略模式 + 责任链模式」构建灵活可扩展的状态引擎,让抽奖系统的状态管理从「混乱战场」变成「有序流水线」。
设计模式 存储 人工智能
73 0
|
3月前
|
设计模式 C++
【实战指南】设计模式 - 工厂模式
工厂模式是一种面向对象设计模式,通过定义“工厂”来创建具体产品实例。它包含简单工厂、工厂方法和抽象工厂三种形式,分别适用于不同复杂度的场景。简单工厂便于理解但扩展性差;工厂方法符合开闭原则,适合单一类型产品创建;抽象工厂支持多类型产品创建,但不便于新增产品种类。三者各有优缺点,适用于不同设计需求。
123 41
|
4月前
|
设计模式 存储 缓存
Netty源码—9.性能优化和设计模式
本文主要介绍了Netty的两大性能优化工具、FastThreadLocal的源码和总结、Recycler的设计理念/使用/四个核心组件/初始化/对象获取/对象回收/异线程收割对象和总结,以及Netty设计模式的单例模式和策略模式。
151 53
|
5月前
|
设计模式 负载均衡 监控
并发设计模式实战系列(2):领导者/追随者模式
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第二章领导者/追随者(Leader/Followers)模式,废话不多说直接开始~
131 0
|
5月前
|
设计模式 监控 Java
并发设计模式实战系列(1):半同步/半异步模式
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第一章半同步/半异步(Half-Sync/Half-Async)模式,废话不多说直接开始~
124 0
|
5月前
|
设计模式 运维 监控
并发设计模式实战系列(4):线程池
需要建立持续的性能剖析(Profiling)和调优机制。通过以上十二个维度的系统化扩展,构建了一个从。设置合理队列容量/拒绝策略。动态扩容/优化任务处理速度。检查线程栈定位热点代码。调整最大用户进程数限制。CPU占用率100%
333 0
|
5月前
|
设计模式 消息中间件 监控
并发设计模式实战系列(3):工作队列
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第三章,废话不多说直接开始~
90 0
|
5月前
|
设计模式 消息中间件 监控
并发设计模式实战系列(5):生产者/消费者
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第五章,废话不多说直接开始~
147 1
|
5月前
|
设计模式 监控 Java
并发设计模式实战系列(6):读写锁
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第六章,废话不多说直接开始~
69 0