当前位置: 首页 > 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…...

C# 面向对象

C# 面向对象编程 面向过程&#xff1a;一件事情分成多个步骤来完成。 把大象装进冰箱 (面向过程化设计思想)。走一步看一步。 1、打开冰箱门 2、把大象放进冰箱 3、关闭冰箱门 面向对象&#xff1a;以对象作为主体 把大象装进冰箱 1、抽取对象 大象 冰箱 门 &#xff0…...

android wifi扫描的capability

混合型加密android11 8155与普通linux设备扫描到的安全字段差别 android应用拿到关于wifi安全的字段&#xff1a; systembar-WifiBroadcastReceiver---- scanResult SSID: Redmi_697B, BSSID: a4:39:b3:70:8c:20, capabilities: [WPA-PSK-TKIPCCMP][WPA2-PSK-TKIPCCMP][RSN-PSK…...

datawhale 2411组队学习:模型压缩4 模型量化理论(数据类型、int8量化方法、PTQ和QWT)

文章目录 一、数据类型1.1 整型1.2 定点数1.3 浮点数1.3.1 正规浮点数&#xff08;fp32&#xff09;1.3.2 非正规浮点数&#xff08;fp32&#xff09;1.3.3 其它数据类型1.3.4 浮点数误差1.3.5 浮点数导致的模型训练问题 二、量化基本方法2.1 int8量化2.1.1 k-means 量化2.1.2 …...

数据分析-48-时间序列变点检测之在线实时数据的CPD

文章目录 1 时间序列结构1.1 变化点的定义1.2 结构变化的类型1.2.1 水平变化1.2.2 方差变化1.3 变点检测1.3.1 离线数据检测方法1.3.2 实时数据检测方法2 模拟数据2.1 模拟恒定方差数据2.2 模拟变化方差数据3 实时数据CPD3.1 SDAR学习算法3.2 Changefinder模块3.3 恒定方差CPD3…...

POD-Transformer多变量回归预测(Matlab)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现POD-Transformer多变量回归预测&#xff0c;本征正交分解数据降维融合Transformer多变量回归预测&#xff0c;使用SVD进行POD分解&#xff08;本征正交分解&#xff09;&#xff1b; 2.运行环境Matlab20…...

Hadoop生态圈框架部署(七)- MySQL安装与配置教程

文章目录 前言一、MySQL安装与配置&#xff08;手动部署&#xff09;1. 下载MySQL2. 上传安装包3. 解压HBase安装包4. 配置4.1 配置 MySQL 的主配置文件 my.cnf4.2 配置 MySQL 服务的脚本 5. 初始化MySQL数据库6. 创建快捷方式7. 启动MySQL服务8. 修改MySQL登录密码8.1 使用临时…...

视频直播5G CPE解决方案:ZX7981PG/ZX7981PMWIFI6网络覆盖

方案背景 视频直播蓬勃发展的当下&#xff0c;传统直播网络联网方式的局限性越来越明显。目前传统直播的局限性主要集中在以下几个方面&#xff1a; 传统直播间网络架构条件有限&#xff0c;可连接WIFI数量少&#xff0c;多终端同时直播难以维持&#xff1b;目前4G网络带宽有限…...

技术周刊 |Google 2024 年首届 Web AI 峰会回顾

大家好&#xff0c;我是童欧巴。见字如面&#xff0c;万事胜意&#xff0c;欢迎来到第 134 期周刊。 大厨推荐 Google 2024 年首届 Web AI 峰会回顾 不仅包括来自谷歌团队的演讲者&#xff0c;如 Chrome 和 MediaPipe&#xff0c;还包括第三方代表&#xff0c;如英特尔、Hug…...

web——upload-labs——第十二关——%00截断

查看源码 分析源码我们可以知道&#xff0c;这里是基于白名单过滤&#xff0c;只允许上传jpg,png,gif&#xff0c;但是这里注意第八行&#xff0c;上传路径是可以控制的&#xff0c;所以可以利用%00截断&#xff0c;来达到上传木马的目的。这里要注意一下&#xff0c;%00截断想…...

ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值。ojdbc8版本23.2.0.0驱动BUG【已解决】

问题描述 JDK8使用ojdbc8驱动操作oracle11g数据库&#xff0c;使用JDBC复用 PreparedStatement 对象执行Insert操作时&#xff0c;报错java.sql.SQLException: ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值。&#xff0c;经测试发现&#xff0c;是预编译对象某个占位符号被赋…...

苏州建设网站哪家好/搜狗推广登录

转别人一篇&#xff0c;讲得挺详细的。 使用标准C的类型转换符&#xff1a;static_cast、dynamic_cast、reinterpret_cast、和const_cast。 3.1 static_cast用法&#xff1a;static_cast < type-id > ( exdivssion ) 该运算符把exdivssion转换为type-id类型&#xff0c;但…...

杨家坪网站建设/seo网站优化方案

MFC 起步沉思录 一直以为学MFC就是往子类继承的虚函数里添加方法就OK了&#xff0c;但自从这个暑假学起MFC以来&#xff0c;就慢慢改变了我的愚见&#xff0c;我越来越懂得了师哥曾经说过的话&#xff0c;精通一门语言的关键还是算法或思想&#xff0c;学习MFC&#xff0c;只是…...

免费制作个人网站app/百度seo刷排名网址

Windows10 网络图标消失 连接不上网络 的解决方法参考文章&#xff1a; &#xff08;1&#xff09;Windows10 网络图标消失 连接不上网络 的解决方法 &#xff08;2&#xff09;https://www.cnblogs.com/jiaxinwei/p/11457228.html &#xff08;3&#xff09;https://www.co…...

table布局网站/app下载量推广

语义 意义语义元素 有意义的元素什么是语义元素?一个语义元素能够清楚的描述其意义给浏览器和开发者。无语义 元素实例: 和 – 无需考虑内容.语义元素实例: , 浏览器支持Internet Explorer 9, Firefox, Chrome, Safari 和 Opera 支持语义元素。注意: Internet Explorer 8 及更…...

怎么做好网站营销/免费企业网站建设流程

一、校验图片的类型、大小 function imageVerify(file, size) {//判断上传的文件后缀是否否和规范for(var i 0; i < file.length; i) {var fileSuffix file[i].name.substr(file[i].name.indexOf("."));//判断图片上传的格式if(fileSuffix ! ".jpg…...

51软件测试网站/广告设计自学教程

在 Windows Vista and Windows 7上, 启动ARM-Cortex-A8_RTSM 平台下的debug配置可能会导致如下错误&#xff1a;DS-5 Debugger 的debug 会话使用telnet&#xff08;不是串行连接&#xff09;控制你的计算机连接到RTSM。这个错误发生在&#xff1a; 当你试图从debugger 连接到R…...