一分钟学会《模板方法模式》

简介: 模板方法模式

前言

只有光头才能变强。

文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y

在上一篇有读者说,一分钟就看完门面模式了,所以今天的标题就取《一分钟学会模板方法模式》

回顾前面所写过的设计模式:

无论是面试还是个人的提升,设计模式是必学的。今天来讲解模板方法模式~

一、模板方法模式

1.1模板方法模式现实例子

大家都知道,我每次写原创技术文章,开头总会有“只有光头才能变强”。我当然不可能每次写文章的时候都去复制这句话(因为这样太麻烦了)。

我有自己的写作模板,给大家看一下:

我的写作模板

前言和最后都是固定下来的,至于第一点和第二点就得看是写什么文章,写不同的文章对应的内容也是不一样的。

每次我写文章的时候,只要在这个模板上添加我自己想写的东西就好了,就不用每次都复制一遍相同的内容,这样就大大减少我的工作量啦。

1.2回到代码世界

代码来源于生活,同样地我可以将我写文章的过程用代码来描述,大家来看一下。

3y每篇文章都会有“前言”和“最后”的内容,3y把这两个模块写出来了。


// 3y的文章模板
public class Java3yWriteArticle {
    
    // 前言
    public void introduction() {
        System.out.println("只有光头才能变强");
    }

    // 最后
    public void theLast() {
        System.out.println("关注我的公众号:Java3y");

    }
}

3y写文章的时候,3y可能就会这样使用:


    // 3y写文章
    public static void main(String[] args) {

        Java3yWriteArticle writeArticle = new Java3yWriteArticle();

        // 前言
        writeArticle.introduction();

        // 实际内容
        System.out.println("大家好,我是3y,今天来给大家分享我写的模板方法模式");

        // 最后
        writeArticle.theLast();
    }

这样是可以完成3y写文章的功能,但是这样做好吗?这时候3y女朋友也想写文章,她的文章同样也想有“前言”和“最后”两个模块,所以3y女朋友的文章模板是这样的:


// 3y女朋友的文章模板
public  class Java3yGFWriteArticle {

    // 前言
    public void introduction() {
        System.out.println("balabalabalalabalablablalab");
    }

    // 最后
    public void theLast() {
        System.out.println("balabalabalalabalablablalab");

    }
}

那3y女朋友写文章的时候,可能也会这样使用:


    // 3y女朋友写文章
    public static void main(String[] args) {
        Java3yGFWriteArticle java3yGFWriteArticle = new Java3yGFWriteArticle();

        // 前言
        java3yGFWriteArticle.introduction();

        // 实际内容
        System.out.println("3y是傻子,不用管他");

        // 最后
        java3yGFWriteArticle.theLast();

    }

可以发现3y和3y女朋友要写文章的时是要重复调用introduction();和theLast();。并且,3y的文章模板和3y女朋友的文章模板中的“前言”和“最后”只是实现内容的不同,却定义了两次,明显就是重复的代码。面对重复的代码我们会做什么?很简单,抽取出来!

于是我们就可以抽取出一个通用的WriteArticle(为了方便调用,我们还将写文章的步骤封装成一个方法):


// 通用模板
public abstract class WriteArticle {

    // 每个人的“前言”都不一样,所以抽象(abstract)
    protected abstract void introduction();

    // 每个人的“最后”都不一样,所以抽象(abstract)
    protected abstract void theLast();


    // 实际要写的内容,每个人的“实际内容”都不一样,所以抽象(abstract)
    protected abstract void actualContent();
    
    // 写一篇完整的文章(为了方便调用,我们将这几个步骤分装成一个方法)
    public final void writeAnCompleteArticle() {

        // 前言
        introduction();

        // 实际内容
        actualContent();

        // 最后
        theLast();
    }
}

所以,3y的模板就可以继承通用模板,在通用模板上实现自己想要的就好了:


// 3y的文章模板
public  class Java3yWriteArticle extends WriteArticle {

    // 前言
    @Override
    public void introduction() {
        System.out.println("只有光头才能变强");
    }

    // 最后
    @Override
    public void theLast() {
        System.out.println("关注我的公众号:Java3y");

    }
    @Override
    protected void actualContent() {
        System.out.println("大家好,我是3y,今天来给大家分享我写的模板方法模式");
    }
}

同样地,3y女朋友的文章模板也是类似的:


// 3y女朋友的文章模板
public  class Java3yGFWriteArticle extends WriteArticle {

    // 前言
    @Override
    public void introduction() {
        System.out.println("balabalabalalabalablablalab");
    }

    // 最后
    @Override
    public void theLast() {
        System.out.println("balabalabalalabalablablalab");

    }

    @Override
    protected void actualContent() {
        System.out.println("3y是傻子,不用管他");
    }
}

想要真正写文章的时候就十分方便了:


    // 3y写文章
    public static void main(String[] args) {

        WriteArticle java3ywriteArticle = new Java3yWriteArticle();
        java3ywriteArticle.writeAnCompleteArticle();
    }

    // 3y女朋友写文章
    public static void main(String[] args) {
        WriteArticle java3yGFWriteArticle = new Java3yGFWriteArticle();
        java3yGFWriteArticle.writeAnCompleteArticle();
    }

要点:

  • 把公共的代码抽取出来,如果该功能是不确定的,那我们将其修饰成抽象方法。
  • 将几个固定步骤的功能封装到一个方法中,对外暴露这个方法,就可以非常方便调用了。

嗯,上面的就是模板方法模式,就这么简单!

1.3模板方法模式介绍

《设计模式之禅》:

定义一个操作中的算法框架,而将一些步骤延迟到子类中。使子类可以不改变一个算法的结构即可重定义该算法的某些步骤。

根据我们上面的例子,来讲讲这段话的含义:

  • 定义一个操作中的算法框架,而将一些步骤延迟到子类中。

    • WriteArticle中有一个writeAnCompleteArticle()方法,该方法定义了发文章的所有步骤,但是这些步骤大多是抽象的,得由子类来实现。
  • 使子类可以不改变一个算法的结构即可重定义该算法的某些步骤

    • 外界是通过调用writeAnCompleteArticle()方法来写文章的,子类如果改变具体的实现就会间接改变了算法的细节。

比如3y在文章模板中的introduction()改了,“只有充钱才能变强”


    @Override
    public void introduction() {
        System.out.println("只有充钱才能变强");
    }

我们没有碰过writeAnCompleteArticle()的代码,但再次调用这个方法的时候,具体的实现就会发生改变(因为writeAnCompleteArticle受子类的具体实现影响)

下面我们看一下模板方法模式的通用类图:

模板方法模式的通用类图

在模板方法模式中,也有几个术语,根据我们的例子中的注释,我给大家介绍一下:


// 抽象模板类
public abstract class WriteArticle {


    // 基本方法
    protected abstract void introduction();

    // 基本方法
    protected abstract void theLast();
    
    // 基本方法
    protected abstract void actualContent();

    // 模板方法
    public final void writeAnCompleteArticle() {
        introduction();
        actualContent();
        theLast();
    }
}

// 具体模板类
public class Java3yWriteArticle extends WriteArticle {

    // 实现基本方法
    @Override
    public void introduction() {
        System.out.println("只有充钱才能变强");
    }

    // 实现基本方法
    @Override
    public void theLast() {
        System.out.println("关注我的公众号:Java3y");
    }

    // 实现基本方法
    @Override
    protected void actualContent() {
        System.out.println("大家好,我是3y,今天来给大家分享我写的模板方法模式");
    }
}
  • 基本方法:在子类实现,并且在模板方法中被调用
  • 模板方法:定义了一个框架,实现对基本方法的调用,完成固定的逻辑。

1.4模板方法的优缺点

优点:

  • 封装不变的部分,扩展可变的部分。把认为是不变的部分的算法封装到父类,可变部分的交由子类来实现!
  • 提取公共部分的代码,行为由父类控制,子类实现!

缺点:

  • 抽象类定义了部分抽象方法,这些抽象的方法由子类来实现,子类执行的结果影响了父类的结果(子类对父类产生了影响),会带来阅读代码的难度!

1.5模板方法模式JDK应用

最经典的就是JUC包下的AQS(AbstractQueuedSynchronizer)了。AQS是什么?

AQS其实就是一个可以给我们实现锁的框架。内部实现的关键是:先进先出的队列、state状态

我们可以看一下AQS定义的acquire()


    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }
    

acquire()相当于模板方法,tryAcquire(arg)相当于基本方法。

tryAcquire方法被多个子类实现

最后

模板方法模式也很简单呀,一个抽象类有基本方法(等着被子类实现的方法),有模板方法(对外暴露、调用基本方法、定义了算法的框架),那就完事了。

推荐阅读和参考资料:

乐于分享和输出干货的Java技术公众号:Java3y。关注即可领取海量的视频资源!

精彩回顾:

觉得我的文章写得不错,不妨点一下赞!

目录
相关文章
|
10天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
7743 13
|
8天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
1668 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
5天前
|
人工智能 JavaScript 芯片
DeepSeek 官方偷偷上传 Harness 桌面端安装包,我已经用上了。。附最新下载地址
DeepSeek Harness 官方的桌面端安装包被网友扒出来了,2 分钟讲明白如何使用,体验如何,适合作为 AI 编程工具么?附最新 Windows 和 Mac 双端的下载地址
1448 1
|
8天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
1304 11
|
22天前
|
人工智能 自然语言处理 安全
阿里云千问办公 QwenWork详细介绍:产品核心能力、典型场景、价格及常见问题解答
千问办公是阿里云推出的一站式AI办公平台,主打"不止于对话,更注重交付",依托通义千问旗舰大模型,用户一句话即可完成数据分析、PPT生成、视频剪辑等复杂任务,直接输出可用成果。产品深度打通钉钉生态与企业OA,覆盖桌面端、网页端,提供企业标准版198元/人/月等多档订阅方案,新用户注册即赠2000积分,适配工程师、HR、财务等多职业办公场景,成为能动手干活的"全能AI同事"。
3694 10
|
7天前
|
人工智能 编解码 并行计算
MiniMax-H3 一键整合包技术文档:8G 显存运行 AI 漫剧制作 —— 角色替换 / 动作迁移 / 文图生视频部署与调参指南
MiniMax H3 是 MiniMax 开源的全模态视频生成模型,支持文/图/音/视多条件输入,输出最高2K、15秒带双声道音频视频。本文档详述其Int8量化版在8GB显存下的本地一键部署、三段式工作流(EDIT/REPLACE/CONTINUE)、参数调优及常见问题排查。(239字)
|
16天前
|
缓存 IDE Java
【保姆级】Android Studio下载、安装和汉化教程(2026最新)
Android Studio 是 Google 官方推出的免费 Android 应用开发集成环境,基于 IntelliJ IDEA,内置模拟器、调试器、性能分析及 Compose 界面工具,功能全面,文档丰富,是安卓开发首选工具。(239字)
1788 1

热门文章

最新文章