Java 设计模式系列:模板方法模式

简介

模板方法模式是一种行为型设计模式,它定义一个操作中的算法骨架,将一些步骤推迟到子类中。模板方法模式使得子类可以不改变一个算法的结构,即可重定义该算法的某些特定步骤。

在模板方法模式中,抽象类中定义了一系列基本操作,这些操作是具体的也可以是抽象的,每一个基本操作对应算法的一个步骤。在子类中可以重定义或实现这些步骤,同时抽象类实现了一个模板方法,定义一个算法的框架。

模板方法模式通过封装不变部分,扩展可变部分,将特定步骤的具体实现与操作流程分离开来,实现了代码的复用和扩展,提高了代码质量和可维护性。同时,由于模板方法模式将具体实现由子类来完成,因此可以方便地扩展新的功能或变更实现方式,同时不影响模板方法本身。

然而,模板方法模式也存在一些缺点。由于每个算法都需要一个抽象类和具体子类来实现,因此在操作流程比较多时可能导致类的数量急剧增加,从而导致代码的复杂性提高。同时,由于模板方法和子类紧密相关,如果该模板方法需要修改,可能会涉及到多个子类的修改。

结构

模板方法(Template Method)模式包含以下主要角色:

  • 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。

    • 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。

    • 基本方法:是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:

      • 抽象方法(Abstract Method) :一个抽象方法由抽象类声明、由其具体子类实现。

      • 具体方法(Concrete Method) :一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。

      • 钩子方法(Hook Method) :在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。

        一般钩子方法是用于判断的逻辑方法,这类方法名一般为isXxx,返回值类型为boolean类型。

  • 具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的组成步骤。

案例实现

【例】炒菜

炒菜的步骤是固定的,分为倒油、热油、倒蔬菜、倒调料品、翻炒等步骤。现通过模板方法模式来用代码模拟。类图如下:

在这里插入图片描述

代码如下:

public abstract class AbstractClass {public final void cookProcess() {//第一步:倒油this.pourOil();//第二步:热油this.heatOil();//第三步:倒蔬菜this.pourVegetable();//第四步:倒调味料this.pourSauce();//第五步:翻炒this.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 ConcreteClass_BaoCai extends AbstractClass {@Overridepublic void pourVegetable() {System.out.println("下锅的蔬菜是包菜");}@Overridepublic void pourSauce() {System.out.println("下锅的酱料是辣椒");}
}public class ConcreteClass_CaiXin extends AbstractClass {@Overridepublic void pourVegetable() {System.out.println("下锅的蔬菜是菜心");}@Overridepublic void pourSauce() {System.out.println("下锅的酱料是蒜蓉");}
}public class Client {public static void main(String[] args) {//炒手撕包菜ConcreteClass_BaoCai baoCai = new ConcreteClass_BaoCai();baoCai.cookProcess();//炒蒜蓉菜心ConcreteClass_CaiXin caiXin = new ConcreteClass_CaiXin();caiXin.cookProcess();}
}

注意:为防止恶意操作,一般模板方法都加上 final 关键词。

优缺点

优点:

  • 提高代码复用性

    将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。

  • 实现了反向控制

    通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 ,并符合“开闭原则”。

缺点:

  • 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
  • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。

源码中的应用

JDK中

  1. java.io.InputStream:这是 Java 输入流的抽象类。它定义了一系列读取字节的方法,如read()read(byte[] b, int off, int len)。它的子类,如FileInputStreamByteArrayInputStream等,实现了这些抽象方法以提供不同的输入来源。

    https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/io/InputStream.java

  2. java.util.AbstractList:这是 Java 集合框架中 List 接口的抽象实现。它实现了 List 接口中的大部分方法,例如get(int index)size(),而add(int index, E element)remove(int index)等修改列表的方法则被定义为抽象,留给具体的子类实现。

    https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/AbstractList.java

  3. javax.servlet.http.HttpServlet:这是 Java Servlet API 中的一个关键类,用于处理 HTTP 请求。HttpServlet定义了doGet()doPost()等用于处理不同 HTTP 方法的抽象方法,开发人员可以通过扩展HttpServlet并覆盖这些方法来编写自定义的 HTTP 请求处理逻辑。

Spring中

  1. JdbcTemplateJdbcTemplate 是 Spring JDBC 模块中的一个核心类,它简化了 JDBC 编程。JdbcTemplate 使用了模板方法模式,定义了一组模板方法,如execute()query()update()等,这些方法定义了 JDBC 操作的通用流程,但将实际的 SQL 查询、参数设置等操作留给了回调接口或者 Lambda 表达式,使得用户可以根据需要进行定制。
  2. RestTemplate:在 Spring Web 模块中,RestTemplate 是一个用于访问 RESTful 服务的客户端类。它也使用了模板方法模式,定义了一组模板方法,如getForObject()postForObject()等,这些方法封装了 HTTP 请求的通用逻辑,但实际的 HTTP 请求发送和响应处理由具体的 HTTP 消息转换器等组件来实现。
  3. AbstractController:在 Spring MVC 中,AbstractController 是一个抽象控制器类,它定义了一些处理请求的模板方法,如handleRequestInternal()。开发者可以通过扩展AbstractController并实现这些模板方法来创建自定义的控制器,从而实现特定的请求处理逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/313366.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

48.基于SpringBoot + Vue实现的前后端分离-雪具销售系统(项目 + 论文PPT)

项目介绍 本站是一个B/S模式系统,采用SpringBoot Vue框架,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得基于SpringBoot Vue技术的雪具销售系统设计与实现管理工作系统…

精通技术写作:如何写出高质量技术文章?

CSDN 的朋友你们好,我是未来,今天给大家带来专栏【程序员博主教程(完全指南)】的第 7 篇文章“如何撰写高质量技术文章”。本文深入探讨了如何写好一篇技术文章。文章给出了好的技术文章的定义和分析,并提供了从选题、…

MDK stm32怎么生成bin文件

第一种 D:\Keil_v5\ARM\ac5.6\bin\fromelf.exe --bin -o ../../Output/atk_f407.bin ../../Output/atk_f407.axf 空格解析 D:\Keil_v5\ARM\ac5.6\bin\fromelf.exe一个空格--bin一个空格-o两个空格../../Output/atk_f407.bin ../../Output/atk_f407.axf (注意后…

回归预测 | Matlab实现GWO-GPR灰狼算法优化高斯过程回归多变量回归预测

回归预测 | Matlab实现GWO-GPR灰狼算法优化高斯过程回归多变量回归预测 目录 回归预测 | Matlab实现GWO-GPR灰狼算法优化高斯过程回归多变量回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现GWO-GPR灰狼算法优化高斯过程回归多变量回归预测 1.Matlab实现…

ASP.NET基于TCP协议的简单即时通信软件的设计与实现

摘 要 即时通信(Instant Message),由于其具有实时性、跨平台性、成本低、效率高等优点而受到广泛的使用。设计并实现一个能够处理多用户进行实时、安全的即时通信系统具有较强的现实意义。即时通信的底层通信是通过SOCKET套接字接口实现的。当前的主流UNIX系统和微…

RocketMQ 之 IoT 消息解析:物联网需要什么样的消息技术?

作者:林清山(隆基) 前言: 从初代开源消息队列崛起,到 PC 互联网、移动互联网爆发式发展,再到如今 IoT、云计算、云原生引领了新的技术趋势,消息中间件的发展已经走过了 30 多个年头。 目前&a…

图神经网络推荐系统

链接(何向南教授):https://hexiangnan.github.io/papers/wsdm22-tutorial-proposal.pdf 摘要: 近年来,图神经网络(graph neural network, GNN)以其强大的结构化数据处理能力和对高阶信息的挖掘能力,成为许…

【Go语言快速上手(二)】 分支与循环函数讲解

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:Go语言专栏⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习更多Go语言知识   🔝🔝 Go快速上手 1. 前言2. 分支与循环2.1…

libtorch+cuda12.0cmake编译失败“Failed to find nvToolsExt”解决办法

博主已安装cuda12.0以及对应的libtorch。 这里可以直接通过安装cuda11.6(cuda11.8也可以)中的【Nsight NVTX】解决。 1、下载CUDA11.6 cuda下载链接 蓝色箭头根据电脑系统win10还是win11自行选择,其余均按图中所以选择。 2、安装 下载完…

集合体系java

Collection:单列集合:每个元素只包含一个值 Collection集合存储的是地址 Collection的三种遍历方法如下 //迭代器是用来遍历集合的专用方式(数组没有迭代器),在java中迭代器的代表是Iterator //boolean hasNext():询问当前位置…

图书管理系统概述

自友图书馆管理系统解决方案适用于中小学、大中专院校以及企事业单位中小型图书馆的自动化管理需求,其功能覆盖了图书馆自动化集成管理业务流程所包括的所有环节。《图书馆管理系统》首先应该按照我国图书馆行业通用CNMARC格式及《中图法第四版》行业标准开发而成,支…

Swift Publisher 5 for mac:打造精美版面

Swift Publisher 5 for mac:打造精美版面 Swift Publisher 5是一款专业的版面设计和编辑工具,为Mac用户提供了强大的设计功能和直观的操作界面。以下是关于Swift Publisher 5的功能介绍: 直观易用的界面:用户能够轻松地使用Swift …

甘特图:项目管理者的必备神器,如何提高工作效率?

甘特图是什么?项目管理者大多都熟悉甘特图,它是一种直观展示项目计划执行过程的工具。通过条形图来显示项目、任务的时间安排,以及实际进度与计划进度的对比情况。 在我个人的项目管理实践中,甘特图确实帮助我提高了工作效率&am…

goproxy 简单介绍 及一键安装脚本

goproxy 官网 https://goproxy.cn/ GoProxy 是一项用于 Go 模块的高性能代理服务,旨在为 Go 开发人员提供更快速、更可靠的模块下载体验。它提供以下主要功能: 全球分布式代理服务器: GoProxy 在全球多个地区部署了代理服务器,例如拉斯维加…

威纶通触摸屏与S7-1200进行标签通信(符号寻址)的具体方法示例

威纶通与S7-1200进行标签通信(符号寻址)的具体方法示例 前面和大家分享了威纶通与S7-1200通过绝对地址进行以太网通信的具体方法,具体内容可参考以下链接中的内容: 威纶通触摸屏与S7-1200以太网通信的具体方法和步骤(非常详细) 如下图所示,打开博途软件,新建一个项目,…

MCU最小系统的电源模块设计和复位模块的设计

最小操作系统就是一个电路,这个电路里面必须要的东西(如人需要喝水吃饭温度等情况,才能或者) 现在我们要解决这三个问题 这里V开头的,都是电源管脚 这里解释一下: 这里要注意哪些是电路电压,哪…

机器学习和深度学习--李宏毅 (笔记与个人理解)Day 16

Day 16 deep Learning – 鱼与熊掌兼得 最近在减重, 昨天跑了个一公里,然后今天上午又打了个篮球,真是老胳膊老腿了,运动完给我困得不行 Review 见前面的笔记 这里说dl 会提供一个足够大的模型, 来使得Dall loss 足够小…

C# 自动填充文字内容到指定图片

目录 需求 开发运行环境 方法设计 实现代码 AddText方法 图片转Base64 调用示例 小结 需求 在我们的一些发布系统项目应用中,会经常发布一些链接图标,该图标基本上以模板背景为主,并填充项目文字内容。解决方式一般会让美工进行制作…

设计模式胡咧咧之策略工厂实现导入导出

策略模式(Strategy Pattern) 定义: 定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。 本质: 分离算法,选择实现 应用场景 何时使用 一个系统有许多类,而区分他们的只是他们直接…

动手学大模型应用开发--Chapter 01 大模型概念

文章目录 前言一、学习知识点概要1.1 LLM1.3 ChatGPT1.3 RAG1.3.1 RAG解决的问题1.3.2 RAG的主要流程: 1.4 LangChain 前言 本学习笔记为datawhale动手学大模型应用开发的学习内容,学习链接为: https://datawhalechina.github.io/llm-univer…