当前位置: 首页 > news >正文

【设计模式】模板方法模式 在java中的应用

设计模式

设计模式是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。这个术语是由Erich Gamma等人在1995年的书《设计模式:可复用面向对象软件的基础》中首次引入的。设计模式可以加快开发过程,提供一种通用的、重复使用的、优雅的解决方案,用于在特定的上下文中处理常见的设计问题。

设计模式可以分为三大类:创建型、结构型和行为型。创建型模式关注如何创建对象,结构型模式关注如何组合对象,而行为型模式则关注对象之间的通信。

模板方法模式

模板方法模式是一种行为设计模式,它在一个方法中定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。

在模板方法模式中,我们将不变的行为移至父类,将可变的行为留给子类实现。父类中的模板方法可以定义一系列的算法步骤,并且可以提供一个默认的实现。这样,子类在必要时可以覆盖这些方法,但是改变的是步骤的具体实现,而不是步骤的执行顺序。

模板方法模式是一种非常灵活的模式,它可以用来处理许多常见的编程问题,例如代码重用、代码组织和控制复杂性。

模板方法模式的定义

模板方法模式是一种行为设计模式,它在一个方法中定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。

模板方法模式的主要特点

  1. 代码复用和封装:模板方法模式通过将公共代码提取到父类中,实现了代码的复用。同时,它封装了具体步骤和数据,保护了算法的完整性和安全性。

  2. 提供统一的接口:父类提供了一个模板方法,定义了算法的骨架。这个模板方法对外提供了统一的接口,使得客户端不需要关心具体的实现细节。

  3. 支持变化:模板方法模式允许子类重写父类的某些步骤,这使得算法可以在不改变其结构的情况下,有选择地改变其行为。

  4. 控制子类的扩展:模板方法模式通过在模板方法中预定义钩子函数,可以控制子类的扩展。钩子是一种特殊的方法,它在父类中声明并给出默认实现,子类可以选择是否覆盖它。

  5. 延迟实现:模板方法模式中的具体步骤可以在子类中实现,这样可以延迟到子类中进行实现。这是所谓的“好莱坞原则”——别打电话给我们,我们会打电话给你。这种原则可以防止“依赖腐败”。

模板方法模式是一种非常灵活的模式,它可以用来处理许多常见的编程问题,例如代码重用、代码组织和控制复杂性。

模板方法模式的基本结构

模板方法模式主要包含以下几个部分:

  1. 抽象类(AbstractClass):这个类定义了一系列的方法,包括模板方法和一些基本方法。模板方法定义了算法的骨架,基本方法是算法中的一个步骤,可以是抽象的,也可以有默认的实现。

  2. 具体类(ConcreteClass):这个类继承抽象类,并实现抽象类中的抽象方法,这些方法是算法中的具体步骤。

UML图解释

-----------------
| AbstractClass |
-----------------
| +templateMethod() |
| #primitiveOperation1() |
| #primitiveOperation2() |
-----------------^|
-----------------
| ConcreteClass |
-----------------
| #primitiveOperation1() |
| #primitiveOperation2() |
-----------------

在这个UML图中:

  • AbstractClass 是一个抽象类,它定义了一个模板方法 templateMethod,以及两个基本方法 primitiveOperation1primitiveOperation2。模板方法 templateMethod 定义了算法的骨架,基本方法 primitiveOperation1primitiveOperation2 是算法中的一个步骤,可以是抽象的,也可以有默认的实现。

  • ConcreteClass 是一个具体类,它继承了 AbstractClass,并实现了 primitiveOperation1primitiveOperation2。这些方法是算法中的具体步骤。

实例背景介绍

假设我们正在开发一个工具库,其中有一个DataParser类,这个类的任务是读取数据,解析数据,然后处理数据。我们有两种类型的数据源:一种是从文件中读取的数据,另一种是从数据库中读取的数据。尽管读取数据的方式不同,但解析和处理数据的方式是相同的。

实例设计与实现

首先,我们定义一个抽象的DataParser类,这个类定义了解析数据的模板方法,模板方法中的一些步骤是抽象的,需要在子类中实现。

public abstract class DataParser {// Template methodpublic final void parseDataAndGenerateReport() {readData();processData();writeReport();}// Abstract methodsprotected abstract void readData();protected abstract void processData();// Common methodpublic void writeReport() {System.out.println("General Report Generation");}
}

然后,我们定义两个DataParser的子类:CSVDataParserDatabaseDataParser,它们分别实现了读取CSV文件和数据库的方法。

public class CSVDataParser extends DataParser {protected void readData() {System.out.println("Reading data from CSV file");}protected void processData() {System.out.println("Processing data from CSV file");}
}public class DatabaseDataParser extends DataParser {protected void readData() {System.out.println("Reading data from database");}protected void processData() {System.out.println("Processing data from database");}
}

代码解析

在上述代码中,DataParser类定义了一个模板方法parseDataAndGenerateReport(),这个方法包含了读取数据,处理数据和生成报告这三个步骤。其中,readData()processData()是抽象方法,需要在子类中实现,而writeReport()是一个具体方法,已经在DataParser类中实现。

CSVDataParserDatabaseDataParser类分别实现了readData()processData()方法,它们分别读取CSV文件和数据库中的数据,并处理这些数据。

这样,无论我们的数据来自于CSV文件还是数据库,我们都可以使用相同的方式来解析数据和生成报告,这就是模板方法模式的优点。

模板方法模式在Java API的应用

在Java API中,有许多地方使用了模板方法模式。例如,java.io.InputStreamjava.io.OutputStreamjava.io.Readerjava.io.Writer的所有非抽象方法,都依赖于这些类的抽象方法。例如,InputStream中的read()方法就是一个模板方法,它依赖于read(byte b[], int off, int len)这个抽象方法。

Java中模板方法模式的实际应用案例

一个常见的Java模板方法模式的应用是在Android的AsyncTask类中。AsyncTask是Android提供的一个轻量级的异步类,它可以直接继承使用。AsyncTask中定义了一些方法,如onPreExecute()doInBackground()onProgressUpdate()onPostExecute()。其中doInBackground()是抽象方法,必须在子类中实现,其他都是模板方法,有默认实现,可以根据需要在子类中重写。

以下是一个简单的示例:

public class DownloadTask extends AsyncTask<String, Integer, String> {protected void onPreExecute() {// 在主线程执行,用于进行一些界面上的初始化,比如显示一个进度条对话框等。}protected String doInBackground(String... params) {// 在子线程中执行,进行耗时操作,比如下载文件等。可以调用publishProgress方法来更新任务的进度。return "Downloaded file";}protected void onProgressUpdate(Integer... progress) {// 在主线程执行,用于更新进度信息。}protected void onPostExecute(String result) {// 在主线程执行,用于处理doInBackground方法的结果。}
}

在上述代码中,doInBackground()方法是抽象的,必须在子类中实现,其他的方法都有默认实现,可以在子类中重写。这就是典型的模板方法模式。

模板方法模式的优点

  1. 代码复用:模板方法模式通过在抽象类中定义算法的骨架,将具体步骤的实现延迟到子类,可以避免代码重复,提高代码复用性。

  2. 封装不变部分:模板方法模式封装了不变的算法步骤,保证了算法的稳定性和可靠性。

  3. 提供扩展点:模板方法模式提供了一个很好的扩展点,即在抽象类中定义的抽象方法,子类可以根据需要重写这些方法,以实现更多的功能。

模板方法模式的缺点

  1. 类数量增多:由于模板方法模式需要为每一个具体的算法步骤定义一个子类,因此可能会导致类的数量增多。

  2. 增加了系统的复杂性:模板方法模式虽然可以提高代码的复用性,但是由于需要定义多个子类,可能会增加系统的复杂性。

  3. 对子类的设计有限制:模板方法模式把基本方法的执行顺序写在模板方法里,这就限制了子类的行为。如果子类需要改变基本方法的执行顺序,那么就需要修改父类的模板方法,这违反了“开闭原则”。

模板方法模式是一种行为设计模式,它定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。

相关文章:

【设计模式】模板方法模式 在java中的应用

设计模式&#xff1a; 设计模式是对软件设计中普遍存在&#xff08;反复出现&#xff09;的各种问题&#xff0c;所提出的解决方案。这个术语是由Erich Gamma等人在1995年的书《设计模式&#xff1a;可复用面向对象软件的基础》中首次引入的。设计模式可以加快开发过程&#x…...

PVE纵览-安装系统卡“Loading Driver”的快速解决方案

PVE纵览-安装系统卡“Loading Driver”的快速解决方案 文章目录 PVE纵览-安装系统卡“Loading Driver”的快速解决方案摘要通过引导参数解决PVE安装卡在“Loading Driver”问题官方解决方法 关键字&#xff1a; PVE、 显卡、 Loading、 Driver、 nomodeset 摘要 在虚拟机…...

Lua资料

Lua脚本语言 cheet sheet Lua & c Lua与C API交互全面解析 Lua语言&#xff1a;和C语言的交互 Lua进阶用法之Lua和C的接口设计 Lua C API 简介 C和Lua之间的相互调用 深入Lua&#xff1a;用户数据userdata 基本数据类型 之 UserData calling-lua-from-c/ Embedding Lua i…...

【C语言】值传递和地址传递

值传递 引用传递&#xff08;传地址&#xff0c;传引用&#xff09;的区别 传值&#xff0c;是把实参的值赋值给行参 &#xff0c;那么对行参的修改&#xff0c;不会影响实参的值。 传地址&#xff0c;是传值的一种特殊方式&#xff0c;只是他传递的是地址&#xff0c;不是普通…...

PyTorch 中使用自动求导计算梯度

使用 PyTorch 进行自动求导和梯度计算 在 PyTorch 中&#xff0c;张量的 requires_grad 属性决定了是否需要计算该张量的梯度。设置为 True 的张量会在计算过程中记录操作&#xff0c;以便在调用 .backward() 方法时自动计算梯度。通过构建计算图&#xff0c;PyTorch 能够有效…...

Oracle Instant Client 23.5安装配置完整教程

Oracle Instant Client 23.5安装配置完整教程 简介环境要求安装步骤1. 准备工作目录2. 下载Oracle Instant Client3. 解压Instant Client4. 安装依赖包5. 配置系统环境5.1 配置库文件路径5.2 配置环境变量 6. 配置Oracle钱包&#xff08;可选&#xff09; 验证安装常见问题解决…...

【jvm】方法区的理解

目录 1. 说明2. 方法区的演进3. 内部结构4. 作用5.内存管理 1. 说明 1.方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码缓存等数据。它是各个线程共享的内存区域。2.尽管《Java虚拟机规范》中把方法区描述为堆的一个逻辑部分&#xff0c;但它却…...

ES-针对某个字段去重后-获取某个字段值的所有值

针对上面表的数据&#xff0c;现在想根据age分组&#xff0c;并获取每个分组后的name有哪些(去重后)。 select age, GROUP_CONCAT(DISTINCT(name)) from testtable group by age ; 结果&#xff1a; 如果想要增加排序&#xff1a; SELECT age, GROUP_CONCAT(DISTINCT name)…...

百度 2025届秋招提前批 文心一言大模型算法工程师

文章目录 个人情况一面/技术面 1h二面/技术面 1h三面/技术面 40min 个人情况 先说一下个人情况&#xff1a; 学校情况&#xff1a;211本中9硕&#xff0c;本硕学校都一般&#xff0c;本硕都是计算机科班&#xff0c;但研究方向并不是NLP&#xff0c;而是图表示学习论文情况&a…...

sglang 部署Qwen2VL7B,大模型部署,速度测试,深度学习

sglang 项目github仓库&#xff1a; https://github.com/sgl-project/sglang 项目说明书&#xff1a; https://sgl-project.github.io/start/install.html 资讯&#xff1a; https://github.com/sgl-project/sgl-learning-materials?tabreadme-ov-file#the-first-sglang…...

fastadmin操作数据库字段为json、查询遍历each、多级下拉、union、php密码设置、common常用函数的使用小技巧

数据库中遇到的操作 查询字段是json的某个值 //获取数据库中某个字段是json中得某个值&#xff0c;进行查询&#xff0c;goods是表中字段&#xff0c;brand_id是json中要查詢的字段。//数据类型一定要对应要不然查询不出来。$map[json_extract(goods, "$.brand_id")]…...

UniApp在Vue3的setup语法糖下自定义组件插槽详解

UniApp在 Vue3的 setup 语法糖下自定义组件插槽详解 UniApp 是一个基于 Vue.js 的跨平台开发框架&#xff0c;可以用来开发微信小程序、H5、App 等多种平台的应用。Vue 3 引入了 <script setup> 语法糖&#xff0c;使得组件的编写更加简洁和直观。本文将详细介绍如何在 …...

springboot上传下载文件

RequestMapping(“bigJson”) RestController Slf4j public class TestBigJsonController { Resource private BigjsonService bigjsonService;PostMapping("uploadJsonFile") public ResponseResult<Long> uploadJsonFile(RequestParam("file")Mul…...

Python学习从0到1 day29 Python 高阶技巧 ⑦ 正则表达式

目录 一、正则表达式 二、正则表达式的三个基础方法 1.match 从头匹配 2.search&#xff08;匹配规则&#xff0c;被匹配字符串&#xff09; 3.findall&#xff08;匹配规则&#xff0c;被匹配字符串&#xff09; 三、元字符匹配 单字符匹配&#xff1a; 注&#xff1a; 示例&a…...

机器学习-web scraping

Web Scraping&#xff0c;通常称为网络抓取或数据抓取&#xff0c;是一种通过自动化程序从网页中提取数据的技术。以下是对Web Scraping的详细解释&#xff1a; 一、定义与原理 Web Scraping是指采用技术手段从大量网页中提取结构化和非结构化信息&#xff0c;并按照一定的规…...

移远通信5G RedCap模组RG255C-CN通过中国电信5G Inside终端生态认证

近日&#xff0c;移远通信5G RedCap模组RG255C-CN荣获中国电信颁发的5G Inside终端生态认证证书。这表明&#xff0c;该产品在5G基本性能、网络兼容性、安全特性等方面已经过严格评测且表现优异&#xff0c;将进一步加速推动5G行业终端规模化应用。 中国电信5G Inside终端生态认…...

Javaweb梳理17——HTMLCSS简介

Javaweb梳理17——HTML&CSS简介 17 HTML&CSS简介17.1 HTML介绍17.2 快速入门17.3 基础标签17.3 .1 标题标签17.3.2 hr标签17.3.3 字体标签17.3.4 换行17.3.8 案例17.3.9 图片、音频、视频标签17.3.10 超链接标签17.3.11 列表标签17.3.12 表格标签17.3.11 布局标签17.3.…...

【Android、IOS、Flutter、鸿蒙、ReactNative 】自定义View

Android Java 自定义View 步骤 创建一个新的Java类&#xff0c;继承自View、ViewGroup或其他任何一个视图类。 如果需要&#xff0c;重写构造函数以支持不同的初始化方式。 重写onMeasure方法以提供正确的测量逻辑。 重写onDraw方法以实现绘制逻辑。 根据需要重写其他方法&…...

win11跳过联网激活步骤

win11跳过联网激活步骤 win11跳过联网激活步骤方法一&#xff1a;使用Shift F10快捷键&#xff08;推荐&#xff09;1. 启动Windows 112. 选择键盘布局或输入法3. 是否想要添加第二种键盘布局4. 让我们为你连接到网络5. 调出管理员模式CMD6. 耐心等待自动重启7. 启动Windows 1…...

利用c语言详细介绍下冒泡排序

软件开发过程中&#xff0c;排序算法是常规且使用众多的方法之一&#xff0c;而冒泡算法又是排序算法中最常规且基本的算法。今天我们利用c语言&#xff0c;图文详细介绍下冒泡算法。 一、图文介绍 我们输入一个数组&#xff0c;数组为【10&#xff0c;5&#xff0c;3&#xf…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

文件上传漏洞防御全攻略

要全面防范文件上传漏洞&#xff0c;需构建多层防御体系&#xff0c;结合技术验证、存储隔离与权限控制&#xff1a; &#x1f512; 一、基础防护层 前端校验&#xff08;仅辅助&#xff09; 通过JavaScript限制文件后缀名&#xff08;白名单&#xff09;和大小&#xff0c;提…...

Redis上篇--知识点总结

Redis上篇–解析 本文大部分知识整理自网上&#xff0c;在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库&#xff0c;Redis 的键值对中的 key 就是字符串对象&#xff0c;而 val…...