Java模板方法模式:定义骨架,允许子类定制行为

Java模板方法模式:定义骨架,允许子类定制行为

摘要:模板方法模式是一种行为设计模式,它在一个方法中定义了一个算法的骨架,允许子类在不改变算法结构的情况下重定义某些步骤的具体内容。本文将详细介绍Java中实现模板方法模式的步骤、优点以及应用场景。

一、引言

在软件开发中,我们经常遇到一些需要在多个地方执行相似操作的情况。这些操作可能具有相同的整体流程,但某些步骤的具体实现可能会有所不同。为了解决这个问题,我们可以使用模板方法模式。模板方法模式允许我们在一个抽象类中定义一个操作中的算法骨架,而将一些步骤延迟到子类中实现。这样,子类可以在不改变算法结构的情况下重新定义某些步骤的具体内容。

二、Java模板方法模式实现

  1. 定义一个抽象类,包含一个模板方法和一些抽象方法(钩子操作):
public abstract class AbstractClass {// 模板方法,定义算法骨架public final void templateMethod() {baseOperation1();requiredOperations1();baseOperation2();hook1();requiredOperations2();baseOperation3();hook2();}// 基本操作,由抽象类实现private void baseOperation1() {System.out.println("AbstractClass says: I am doing the bulk of the work");}private void baseOperation2() {System.out.println("AbstractClass says: But let subclasses override some operations");}private void baseOperation3() {System.out.println("AbstractClass says: But I am doing the bulk of the work anyway");}// 需要被子类实现的操作protected abstract void requiredOperations1();protected abstract void requiredOperations2();// 钩子操作,提供默认实现,子类可以选择性覆盖protected void hook1() {}protected void hook2() {}
}
  1. 创建具体子类,继承抽象类并实现其中的抽象方法:
public class ConcreteClass1 extends AbstractClass {@Overrideprotected void requiredOperations1() {System.out.println("ConcreteClass1 says: Implemented Operation1");}@Overrideprotected void requiredOperations2() {System.out.println("ConcreteClass1 says: Implemented Operation2");}@Overrideprotected void hook1() {System.out.println("ConcreteClass1 says: Overridden Hook1");}
}public class ConcreteClass2 extends AbstractClass {@Overrideprotected void requiredOperations1() {System.out.println("ConcreteClass2 says: Implemented Operation1");}@Overrideprotected void requiredOperations2() {System.out.println("ConcreteClass2 says: Implemented Operation2");}
}
  1. 客户端代码使用模板方法:
public class Client {public static void main(String[] args) {AbstractClass abstractClass1 = new ConcreteClass1();AbstractClass abstractClass2 = new ConcreteClass2();abstractClass1.templateMethod();abstractClass2.templateMethod();}
}

三、模板方法模式的优点

  1. 封装不变部分,扩展可变部分:把认为是不变部分的算法封装到父类实现,而可变部分则可以通过继承来继续扩展。
  2. 提取公共部分代码,便于维护:模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤,减少了代码重复,提高了代码的可维护性。
  3. 行为由父类控制,子类实现:模板方法模式中的算法骨架由父类控制,子类只需要实现特定的步骤,这使得父类可以更好地控制整个流程的执行顺序和执行条件。

四、模板方法模式的应用场景

  1. 避免代码重复:
    当多个子类中存在公共的行为或操作时,可以将这些公共的部分提取到一个公共的父类中,并使用模板方法模式来定义这个公共的行为。通过将这些共同的步骤放入一个模板方法中,可以让所有的子类共享这些方法,从而消除了重复的代码。例如,在软件开发框架中,通常会有一些固定的处理流程,这些流程可以被定义为模板方法,而具体的业务逻辑则由用户根据实际需求在子类中实现。

  2. 框架设计:
    在框架设计中,模板方法模式是一种常见的设计模式。框架通常提供了一些通用的处理流程和功能,但同时也需要用户根据具体需求来定制某些特定的行为。通过使用模板方法模式,框架可以定义一些模板方法来表示通用的处理流程,并允许用户通过扩展子类来实现特定的功能。这样,既保证了框架的通用性和灵活性,又降低了用户的使用难度。

  3. 游戏开发:
    在游戏开发中,模板方法模式也是一种非常有用的设计模式。游戏通常具有一些固定的流程和规则,如角色的移动、攻击、防御等。这些固定的流程和规则可以使用模板方法模式来定义,而游戏的具体细节(如角色行为、关卡设计等)则可以通过子类来实现和扩展。例如,可以定义一个游戏角色的基类,其中包含一个模板方法来定义角色的通用行为(如移动),然后为不同的角色创建子类,并在子类中实现特定的行为(如攻击方式、技能等)。

  4. 需要控制子类扩展但又希望提供扩展点:
    有些情况下,我们希望定义一个算法或处理流程的基本骨架,并允许子类在必要时增加新的操作,但又不想让子类完全自由地修改整个算法或流程。这时,可以使用模板方法模式来控制子类的扩展。通过在模板方法中定义一些“钩子”(hook)方法或抽象方法,可以让子类在特定的点进行扩展,而不会破坏原有的算法结构或逻辑。这样既可以保证算法或流程的稳定性和一致性,又提供了足够的灵活性来满足不同的需求。

五、总结

Java模板方法模式是一种行为型设计模式,其核心思想是在一个抽象类中定义一个算法的骨架,并允许子类在不改变算法结构的情况下定制某些步骤的具体行为。通过这种方式,模板方法模式实现了算法的不变部分与可变部分的分离,提高了代码的复用性和灵活性。

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

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

相关文章

光纤跳线的大方头跳线、小方头跳线、圆头跳线

光纤跳线在数据中心的应用非常广泛,它普遍应用在光纤通信系统 、光纤接入网、光纤设备传输以及局域网等领域。在光纤通信快速 发展和各种设备需求扩大的推动下,更多类型的光纤跳线被研发出 以及被使用。大家可能听说过LC、SC、FC、ST等跳线,那…

uniapp:APP端webview拦截H5页面跳转,华为市场发布需要限制webview的H5页面跳转

在使用uniapp开发APP项目时,华为市场上线APP会被打回来:您的应用内容存在点击跳转至第三方应用市场或游戏中心下载渠道的问题,不符合华为应用市场审核标准。 华为审核指南4.6 因此可以考虑下面的处理方式,通过拦截webview页面的…

寒假学习总结

经过一个寒假的学习 学了许多的关于数据结构知识 栈与队列,优先队列,单调栈,单调队列,双端队列https://blog.csdn.net/2301_81794044/article/details/135871598?spm1001.2014.3001.5501深搜和广搜https://blog.csdn.net/2301_…

Linux命令 - 如何查询当前已使用的内存占比

结果先行 free -h | awk NR2{printf "%.2f%%", $3*100/$2 }解释一下 这个命令组合了 free -h 和 awk 命令来输出已用内存的百分比。我们一步一步来解析这个命令: Step 1 free -hfree 是一个用来显示 Linux 系统内存使用情况的命令。-h 参数是 “human…

成功解决TypeError: can‘t multiply sequence by non-int of type ‘float‘

🔥 成功解决TypeError: can’t multiply sequence by non-int of type ‘float’ 📅 日期:2024年2月23日 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化…

Intel处理器虚拟化技术VT-x86下实现小型虚拟化框架(1)

一.前言 我一直觉得,学习计算机中的一门新技术,一定要从历史去了解他的全貌。这样有利于我们了解事情的来龙去脉和发展的过程。一上来直接接触新兴事物,很容易陷入不知从何下手的困境。不了解历史发展,就不明白前人的一些操作。因…

FAISS+bge-large-zh在大语言模型LangChain本地知识库中的作用、原理与实践

文章目录 FAISSbge-large-zh在大语言模型LangChain本地知识库中的作用、原理与实践引言FAISS与bge-large-zh简介FAISS原理bge-large-zh原理 FAISSbge-large-zh在LangChain本地知识库中的作用提高检索效率增强语义理解能力支持大规模数据处理 实践数据准备与处理FAISS索引构建与…

Xcode中App图标和APP名称的修改

修改图标 选择Assets文件 ——> 点击Applcon 换App图标 修改名称 点击项目名 ——> General ——> Display Name

Servlet(2)

文章目录 更方便的部署方式安装 Smart Tomcat 插件配置 Smart Tomcat 插件 访问出错怎么办出现 404出现 405出现 500出现 "空白页面"出现 "无法访问此网站" 小结 更方便的部署方式 手动拷贝 war 包到 Tomcat 的过程比较麻烦. 我们还有更方便的办法. 此处我…

用CSS制作弧形卡片的三种创意方法!

在平时开发中,有时候会碰到下面这种“弧形”样式,主要分为“内凹”和“外凸”两种类型,如下 该如何实现呢?或者想一下,有哪些 CSS 属性和“弧形”有关?下面介绍 3 种方式,一起看看吧 一、borde…

智慧校园的未来已来!AI与数字孪生领航教育新时代

随着科技的飞速发展,人工智能(AI)和数字孪生技术正逐渐渗透到我们生活的方方面面,而在教育领域,它们的结合更是催生出一种全新的智慧校园模式。这种模式的出现,不仅预示着教育管理方式的彻底变革&#xff0…

网络原理 - HTTP/HTTPS(5)

HTTPS HTTPS也是一个应用层协议.在HTTP协议的基础上引入了一个加密层. HTTP协议内容都是按照文本的方式明文传输的. 这就导致了在传输过程中出现了一些被篡改的情况. 臭名昭著的"运营商劫持" 下载一个天天动听. 未被劫持的效果,点击下载按钮,就会弹出天天动听的…

【linux】常见指令 -通配符,数据管道,重定向,压缩打包...

目录 前言 基本指令 ls命令 常见选项 ​编辑 pwd命令 cd 指令 常见选项 touch指令 mkdir指令 常见选项 rm 指令 常见选项 man指令 cp指令 常用选项: mv指令 常用选项 nano指令 如何写入且执行文件? cat指令 常用选项 more指令…

基于RK3399 Android11适配OV13850 MIPI摄像头

目录 1、原理图分析2、编写和配置设备树3、调试方法4、遇到的问题与解决5、补丁 1、原理图分析 从上图可看出,我们需要关心的,①MIPI数据和时钟接口使用的是MIPI_TX1/RX1 ②I2C使用的是I2C4总线 ③RST复位引脚使用的是GPIO2_D2 ④PWDN使用的是GPIO1_C7 ⑤…

【Python笔记-设计模式】外观模式

一、说明 外观模式是一种结构型设计模式,能为程序库、框架或其他复杂类提供一个统一的接口。 (一) 解决问题 简化复杂系统的接口调用 (二) 使用场景 简化复杂系统:需要一个指向复杂子系统的直接接口, 且该接口的功能有限时重构复杂的代码…

unity ui界面优化

优化一个比较复杂的界面,里面有多个rt和组件。 在初次打开这个界面的时候会发生1s多的卡顿,还是非常严重的。 分析 通过profiler分析 1.打开界面时卡顿。 分析:除了update和dotween相关逻辑,主要在于打开时的lua function调用…

幻兽帕鲁(Palworld 1.4.1)私有服务器搭建(docker版)

文章目录 说明客户端安装服务器部署1Panel安装和配置docker服务初始化设置设置开机自启动设置镜像加速 游戏服务端部署游戏服务端参数可视化配置 Palworld连接服务器问题总结 说明 服务器硬件要求:Linux系统/Window系统(x86架构,armbian架构…

[程序员] sipp运行时socket接收队列持续满载 - 文件系统访问慢

​今天谈一下,最近和同事一块看到的一个例子,说sipp运行时的某一时刻之后,总是会有408/487/retrans,通过netstat看,还总是会出现接收队列满载的情况。如下netstat的输出,137472是接收队列的缓存的数据量: udp 131072 0 100.103.238.11:5060 0.0.0.0:* 20175/sipp.lates…

spring boot3登录开发-3(账密登录逻辑实现)

⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 🌊山高路远,行路漫漫,终有归途。 目录 前置条件 内容简介 用户登录逻辑实现 创建交互对象 1.创建用户登录DTO 2.创建用户登录VO 创建自定义登录业务异…

K8S简单学习

目录 安装启动第一个服务启动k8s看板暴露服务查看services自动打开服务查看pods 官方的文档 安装 centos8安装记录 pod和deployment的关系 启动第一个服务 通过deployment的方式进行创建 kubectl create deployment hello-nginx --imagenginx:latest --port8080启动k8s看板…