当前位置: 首页 > 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. 对子类的设计有限制:模板方法模式把基本方法的执行顺序写在模板方法里,这就限制了子类的行为。如果子类需要改变基本方法的执行顺序,那么就需要修改父类的模板方法,这违反了“开闭原则”。

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

http://www.lryc.cn/news/487247.html

相关文章:

  • PVE纵览-安装系统卡“Loading Driver”的快速解决方案
  • Lua资料
  • 【C语言】值传递和地址传递
  • PyTorch 中使用自动求导计算梯度
  • Oracle Instant Client 23.5安装配置完整教程
  • 【jvm】方法区的理解
  • ES-针对某个字段去重后-获取某个字段值的所有值
  • 百度 2025届秋招提前批 文心一言大模型算法工程师
  • sglang 部署Qwen2VL7B,大模型部署,速度测试,深度学习
  • fastadmin操作数据库字段为json、查询遍历each、多级下拉、union、php密码设置、common常用函数的使用小技巧
  • UniApp在Vue3的setup语法糖下自定义组件插槽详解
  • springboot上传下载文件
  • Python学习从0到1 day29 Python 高阶技巧 ⑦ 正则表达式
  • 机器学习-web scraping
  • 移远通信5G RedCap模组RG255C-CN通过中国电信5G Inside终端生态认证
  • Javaweb梳理17——HTMLCSS简介
  • 【Android、IOS、Flutter、鸿蒙、ReactNative 】自定义View
  • win11跳过联网激活步骤
  • 利用c语言详细介绍下冒泡排序
  • C# 面向对象
  • android wifi扫描的capability
  • datawhale 2411组队学习:模型压缩4 模型量化理论(数据类型、int8量化方法、PTQ和QWT)
  • 数据分析-48-时间序列变点检测之在线实时数据的CPD
  • POD-Transformer多变量回归预测(Matlab)
  • Hadoop生态圈框架部署(七)- MySQL安装与配置教程
  • 视频直播5G CPE解决方案:ZX7981PG/ZX7981PMWIFI6网络覆盖
  • 技术周刊 |Google 2024 年首届 Web AI 峰会回顾
  • web——upload-labs——第十二关——%00截断
  • ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值。ojdbc8版本23.2.0.0驱动BUG【已解决】
  • win10 自带 directx 修复工具怎么用?最新 directx 修复工具使用方法介绍