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

Yolov8-pose关键点检测:训练实战篇 | 手部关键点检测 yolo8-pose实战检测手部关键点并优化。 阅读详情

前言

只有光头才能变强。

文本已收录至我的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。关注即可领取海量的视频资源!

帅的人都关注了

精彩回顾:

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

STM32 USB键盘实现指南 在STM32上实现键盘功能可以通过USB HID(人机接口设备)协议来实现,使STM32设备能被计算机识别为标准键盘。通过上述步骤,您可以在STM32上实现一个功能完整的USB键盘。关键点包括:正确配置USB HID设备实现键盘矩阵扫描处理按键事件并生成HID报告优化按键响应和消抖处理添加额外功能如宏键和LED反馈这个实现可以作为基础,进一步扩展为游戏键盘、宏键盘或特殊输入设备。 阅读详情

相关推荐

LVDS接口总结--(0)LVDS硬件电路接口

xilinx LVDS接口硬件总结

zidan1412的博客 9721

模板方法模式(模板方法设计模式)详解

参考地址 AQS定义的抽象方法,在子类实现有用到模版方法设计模式. 前言 在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。 例如,去银行办理业务一般要经过以下4个流程:取号、排队、办理具体业务、对银行工作人员进行评分等,其中取号、排队和对银行工作人员进行评分的...

一万个小时 583

基于GEC6818开发板的C/C++贪吃蛇小游戏

f.开始游戏(进入游戏,并没有马上开游戏,需要点击播放才能开始)2.相关宏,全局变量(可以根据自己需要进行修改)k.显示文字前的相关初始化。k.自定义font.h文件。1.需要的主要头文件。l.在开发板上显示字1。m.在开发板上显示字2。a.显示固定大小图片。h.线程1:获得坐标。

2301_77273301的博客 2132

这是一篇java3y的优选文章总结

目录 Java基础: 2018年如何快速学Java: 泛型就这么简单: 注解就这么简单: 数据库连接池就是这么简单: Object对象你真理解了吗? JDK10都发布了,nio你了解多少?: COW奶牛!Copy On Write机制了解一下 给女朋友讲解什么是Optional【JDK 8特性】 还在用Synchronized?Atomic你了解不? JVM如何从入门到放弃的? Java容器 Collection总览 List集合就这么简单【源码剖析】 Map集合、散列表.

Lonely Programmer 8063

transformer优化(一)-UNeXt 学习笔记

​它在早期阶段使用卷积,在潜在空间阶段使用 MLP。通过一个标记化的 MLP 块来标记和投影卷积特征,并使用 MLP 对表示进行建模。 ​

PLANTTHESON的博客 2033

从零到一:R与RStudio的安装与配置全攻略

本文提供了R与RStudio的完整安装与配置指南,涵盖Windows、Mac和Linux三大操作系统。从基础环境搭建到高级性能优化,详细介绍了R语言安装、RStudio配置、项目管理和实用技巧,帮助数据科学初学者快速搭建高效的分析工作环境。

weixin_29062671的博客 420

如何学习 Spring ?学习 Spring 前要学习什么?

学习完java核心技术卷一后该掌握什么知识才能学习spring? 学习完Java基础,想要继续学习JavaWeb的基础,我推荐的是下面这个路线(有帮助,记得点赞!): 一、学习Servlet和Tomcat •Servlet+Tomcat •Tomcat就是这么简单 •Servlet第一篇【介绍Servlet、HTTP协议、WEB目录结构、编写入门Servlet程序、Servlet生命周期】 •Se...

weixin_33937499的博客 1万+

智能车浅谈——手把手让车跑起来(电磁篇)

手把手让你的电磁车上路。

qq_41954556的博客 7万+

目录|Java3y最全目录(2019-6-13更新)

电脑端可以在GitHub上查看所有的目录我都整理好了,欢迎star:https://github.com/ZhongFuCheng3y/3yJava基础2018年如何快速...

3y 2421

智能能效管家:基于 ESP32 的智能插座设计与精细化功耗管理实现

针对传统插座无法远程控制、功耗监测缺失、能源浪费严重等问题,本文设计一款基于 ESP32 主控芯片的智能插座。该系统集成 WiFi 无线通信、交流功耗采集、继电器通断控制模块,实现四大核心功能。硬件采用模块化选型与安全接线设计,软件基于 Arduino-ESP32 框架开发,搭载 Mqtt 通信协议与功耗算法,可通过手机 / 云端实时管控设备,有效提升用电安全性与能源利用率。:ESP32;智能插座;功耗管理;远程控制;能耗监测。

weixin_42300449的博客 101

apollo-减速带通行

主车在通过减速带时速度不超过3m/s

是菜鸟o的博客 389

公众号所有的文章导航(8-15更新)

3y 3054

【DRAM存储器一】基本存储单元、阵列结构、读写原理

详述DRAM存储器存储单元、存储阵列结构和读写原理

highman110的博客 7256

金三银四,二月就要准备!

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y大家都知道金三银四这么一个道...

3y 1872

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

推荐一个java技术文章公众号

☕️Java基础 2018年如何快速学Java 泛型就这么简单 注解就这么简单 Druid数据库连接池就是这么简单 Object对象你真理解了吗? JDK10都发布了,nio你了解多少? COW奶牛!Copy On Write机制了解一下 给女朋友讲解什么是Optional【JDK 8特性】 还在用Synchronized?Atomic你了解不? 《阿里巴巴 Java开发手册》读后感 JVM如...

神棍之路 3198

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

2022最新学习资料链接

🍭 项目系列 揭秘!消息管理平台实现原理 广告系统基础入门 CPS?淘宝客这项技术是什么实现的? 揭秘!待更新...(最新首发公众号,导航更新可能有延迟) 💵 面试系列 《求求大厂给个Offer》简历 《求求大厂给个Offer》List面试题 《求求大厂给个Offer》Map面试题 《求求大厂给个Offer》:多线程基础面试题 《求求大厂给个Offer》:待更新...(最新首发公众号,导航更新可能有延迟) ☕️ 原创电

u013707288的博客 1008

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【生活现场】从搬家到容器技术docker应用场景解析

本文作者:channingbreeze公众号来源:互联网侦察小史是一个非科班的程序员,虽然学的是电子专业,但是通过自己的努力成功通过了面试,现在要开始迎接新生活了。对小...

3y 369

十年架构师吐血整合Java开发必备宝典,凭借这份宝典定级腾讯T3-4

从Java基础、JavaWeb基础到常用的框架再到面试题都有完整的教程,几乎涵盖了Java后端必备的知识点。很多知识点我还在不停的总结和完善。点击关注获取最新文章 资料全部真实有效,不会缺页,不会只是大纲、导图!!!由于文章篇幅有限,为了不耽误大家宝贵的时间,这份PDF小编已经为大家整理好了,需要免费领取的朋友麻烦帮忙转发、转发、转发这篇文章(一定要转发哦),然后私信小编【大全】。 我希望这篇文章: 能给你学习时带来帮助 能给你感受文章的温度 能帮助你构建知识体系 ... 各类知识点总.

文章中资料均可获取,有需要请添加yunduoa2019即可 507

一波囤书好机会!⎡送书+文章导航⎦

前言只有光头才能变强。直奔主题:这几天是囤书的好机会,机不可失!四本《重构 改善既有代码的设计 第2版 全彩精装版》免费送!(当前售价122!)至2019年-4月-15号...

3y 949

Head First 设计模式[总结]

模式:是在某种情境下,针对某问题的某种解决方案。 愿力与你同在:目标和约束 编程真理:CHANGE OO基础:抽象 封装 继承 多态 设计原则: 1 封装变化。找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。 2 针对接口编程,而不是针对实现编程。 3 多用组合,少用继承。 4 为了交互对象之间的松耦合设计而努力。 5 开放-关闭原则。类应

墨家剑客的专栏 885

3Y面试宝典

` ???? 对线面试官面试系列 【对线面试官】简历 【对线面试官】Java注解 【对线面试官】Java泛型 【对线面试官】Java NIO 【对线面试官】Java反射 && 动态代理 【对线面试官】多线程基础 一周两篇持续更新中,文章首发公众号 ☕️ 原创电子书 下面的文章都有对应的原创精美PDF,在持续更新中,可以来找我催更~ 47页的SpringMVC 92页的Mybatis 129页的多线程 141页的Servlet 158页的JSP 76页的集合 64页的JDBC 105

weixin_49574902的博客 794

导航网站java源码_一波囤书好机会!送书+文章导航

前言只有光头才能变强。直奔主题:这几天是囤书的好机会,机不可失!四本《重构 改善既有代码的设计 第2版 全彩精装版》免费送!(当前售价122!)至2019年-4月-15号公众号所有发过的⎡原创⎦文章一、囤书啦!我们都知道,技术书其实都不太便宜,我每次都是在优惠的时候再囤一波自己心爱的书的。(比如在618、双十一、书香节)。但不用等这么久了,现在就有这么一个机会啦!全品类200减30优惠码...

weixin_39656206的博客 209

怎样设计一个好架构:八个评价维度、四层思考深度,以及 23 种设计模式各自解决什么问题

架构要解决的是变化、理解、故障和协作的成本。本文从耦合、可迁移、可适配、复杂度等八个维度讲怎么评价架构,讲维度之间怎么取舍、架构思考可以分几层,再用可编译的 C 代码过一遍 23 种设计模式。

weixin_52400878的博客 333
上一篇: 【生活现场】从搬家到容器技术docker应用场景解析
下一篇: Docker入门资源【整理】
Java3y
Java3y 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 1万+粉丝 509原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值