java设计模式学习之【模板方法模式】

文章目录

  • 引言
  • 模板方法模式简介
    • 定义与用途
    • 实现方式
  • 使用场景
  • 优势与劣势
  • 在Spring框架中的应用
  • 游戏设计示例
  • 代码地址

引言

设想你正在准备一顿晚餐,无论你想做意大利面、披萨还是沙拉,制作过程中都有一些共同的步骤:准备原料、加工食物、摆盘。这里,整个烹饪流程就像一个模板,而具体的菜肴则在这个模板的基础上添加了特有的步骤。在软件开发中,我们经常遇到类似的情况,某些过程的结构相同,但某些步骤的具体实现不同。模板方法模式正是用于解决这类问题的一种设计模式,它在定义算法骨架的同时,将一些步骤的实现延迟到子类。

模板方法模式简介

定义与用途

模板方法模式(Template Method Pattern)是一种行为型设计模式,它在父类中定义了一个操作的算法骨架,而将一些步骤的具体实现延迟到子类中。通过这种方式,可以重新定义算法的某些步骤而不改变算法的结构。

实现方式

实现模板方法模式通常涉及以下几个关键组件:

  • 抽象类(Abstract Class):定义了模板方法和算法的骨架。模板方法设置为 final,这样它就不能被重写。它调用一系列的操作,其中一些操作由子类实现。
  • 具体类(Concrete Class):实现抽象类中的抽象方法,定义了算法中与特定主题相关的步骤。

使用场景

模板方法模式适用于以下场景:

  • 当有多个算法具有相同的算法结构,但算法的某些步骤在不同的情况下有不同的实现时。
  • 当需要控制子类扩展的点时,可以在一些操作中定义钩子(hook)。

例如:

  • 数据解析框架: 定义一个解析数据的模板方法,具体的解析步骤如读取数据、分析数据和处理数据可以在子类中实现。
  • 软件构建过程: 软件构建工具可以定义一系列构建步骤的模板,如清理、编译、测试和打包,具体的步骤根据不同的项目而定制。
  • 游戏设计: 游戏可以定义一个游戏流程模板,如开始游戏、进行游戏和结束游戏,具体的游戏逻辑在不同的游戏子类中实现。

优势与劣势

  • 优势
    • 提供了代码复用的平台,通过模板方法,公共代码移动到单一位置,减少代码冗余。
    • 提供了一种扩展部分算法的方法,子类可以在不改变算法结构的情况下重新定义算法的某些特定步骤。
  • 劣势
    • 对于每个不同的实现,都需要一个新的子类,可能会导致系统中类的数量增加。
    • 有时候可能违背了里氏替换原则,因为子类改变了父类的预期行为。

在Spring框架中的应用

1. JdbcTemplate
JdbcTemplate 是Spring提供的一个优秀的数据库操作工具,它实现了模板方法模式。Spring定义了一个抽象的 JdbcOperations 接口,提供了执行数据库操作的模板方法。JdbcTemplate 类实现了这些方法,管理数据库连接、声明语句的创建和执行、结果集的遍历处理等。用户只需要提供SQL语句和定义如何映射结果集到对象,其他的数据库操作细节(如异常处理、事务管理等)都由模板方法处理。2. TransactionTemplate
Spring的 TransactionTemplate 也是模板方法模式的一个应用实例。它提供了一个模板,用于执行带有事务管理的代码块。用户只需要提供需要在事务环境中执行的代码,而事务的管理(开始、提交、回滚等)则是在模板内部处理的。这使得用户不需要直接与底层的事务API打交道,简化了事务管理的代码。3. Spring Web MVC
在Spring Web MVC框架中,DispatcherServlet 提供了一个模板方法来处理HTTP请求。它定义了处理请求的整体流程:解析请求、寻找对应的处理器、渲染视图等。在这个流程中,可以插入各种预处理器、后处理器和视图解析器来定制请求处理的行为。开发者通过扩展特定的方法,提供自己的处理逻辑。4. Spring Security
Spring Security中的过滤器链也是一个模板方法模式的实例。它定义了一系列的安全检查过程,每一个过滤器都是一个检查的实现。开发者可以通过添加或移除过滤器,或者自定义过滤器来定制安全检查的流程。

游戏设计示例

在这里插入图片描述
步骤 1:创建一个带有模板方法的抽象类

public abstract class Game {abstract void initialize();abstract void startPlay();abstract void endPlay();// 模板方法public final void play(){// 初始化游戏initialize();// 开始游戏startPlay();// 结束游戏endPlay();}
}

Game 是一个抽象类,定义了三个抽象方法:initialize、startPlay 和 endPlay,用于子类实现具体的游戏初始化、开始和结束的行为。它还定义了一个模板方法 play,该方法按顺序调用这三个方法,设置为 final 以防止子类覆盖。

步骤 2:创建扩展上述类的具体类

public class Cricket extends Game {@Overridevoid endPlay() {System.out.println("板球游戏结束了!");}@Overridevoid initialize() {System.out.println("板球游戏初始化了!开始玩吧。");}@Overridevoid startPlay() {System.out.println("板球游戏开始了。享受游戏!");}
}

Cricket 是 Game 的一个具体子类,它实现了板球游戏的具体行为。

public class Football extends Game {@Overridevoid endPlay() {System.out.println("足球游戏结束了!");}@Overridevoid initialize() {System.out.println("足球游戏初始化了!开始玩吧。");}@Overridevoid startPlay() {System.out.println("足球游戏开始了。享受游戏!");}
}

Football 是另一个具体的 Game 子类,实现了足球游戏的具体行为。

步骤 3:使用游戏的模板方法 play() 来演示游戏的定义方式

public class TemplatePatternDemo {public static void main(String[] args) {Game game = new Cricket();game.play();System.out.println();game = new Football();game.play();      }
}

在这里插入图片描述

在这个演示类中,先创建了一个 Cricket 对象,并调用其 play 方法来执行整个板球游戏流程。然后,创建了一个 Football 对象,并再次调用 play 方法来执行足球游戏流程。

这个示例演示了模板方法模式如何定义算法的骨架,同时将一些步骤的具体实现延迟到子类中。通过这种方式,Cricket 和 Football 可以有自己独特的游戏流程,同时共享游戏流程的结构。这使得算法的结构定义一次,可以被多次复用,而且更容易进行扩展。

代码地址

23种设计模式相关代码后续会逐步提交到github上,方便学习,欢迎指点:
代码地址
https://github.com/RuofeiSun/lf-23Pattern

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

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

相关文章

力扣题目学习笔记(OC + Swift)25. K 个一组翻转链表

K 个一组翻转链表 给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。 k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。 你不能只是单纯的改…

年薪最高160万,鸿蒙开发者迎来黄金期!

华为正致力于让鸿蒙系统(HarmonyOS)成为中国的 Andorid。 鸿蒙操作系统诞生于 2019 年,彼时恰逢华为被禁止使用谷歌应用。一晃 4 年,鸿蒙操作系统已经更新到了 4.0 版本,截止今年 8 月,已有超过 7 亿台设备…

播放海康摄像头直播流使用笔记

1、将海康摄像头绑定到萤石云平台&#xff0c;并查看直播流 2、项目中使用 1、安装hls cnpm i hls.js 2、封装组件&#xff08;在components文件夹下新建bodyCapture文件夹下index.vue&#xff09; <template><el-dialogtitle"遗体抓拍"class"bo…

【ArkTS入门】ArkTS开发初探:语言特点和开发特点

什么是ArkTS&#xff1f; ArkTS是一个为鸿蒙组件而生的框架&#xff0c;语法亲人好用。基于TypeScript&#xff0c;ArkTS拓展了声明式UI、状态管理等的能力&#xff0c;从本质上来讲&#xff0c;是TypeScript的扩展&#xff0c;主要服务于前端。 ArkTS的开发可以满足“一次开…

Vite+Vue3学习笔记(2)——语法、渲染、事件、数据传递、生命周期、第三方库、前端部署

官网链接&#xff1a;https://cn.vuejs.org/ 如果出现普通用户无法新建项目&#xff0c;必须要管理员身份新建&#xff0c;那么可以在nodejs的安装路径设置安全选项&#xff0c;提高普通用户的权限。 具体方法参考&#xff1a; https://blog.csdn.net/weixin_43174650/article/…

CSS 缩减中心动画

<template><!-- mouseenter"startAnimation" 表示在鼠标进入元素时触发 startAnimation 方法。mouseleave"stopAnimation" 表示在鼠标离开元素时触发 stopAnimation 方法。 --><!-- 容器元素 --><div class"container" mou…

Python教程(18)——python文件操作详解

Python文件操作 Python文件操作基础操作使用with语句管理文件处理文件操作的异常处理文件路径 文本格式和二进制格式文本格式 (Text Mode)二进制格式 (Binary Mode)例子说明 文件操作的相关函数 所谓的文件操作是指对计算机中的文件进行读取、写入、修改和删除等操作。简单来说…

超赞的进度条控件

© 2012 Conmajia, 2011 Graham Wilson SN: 125.2 本文为 CodeProject 2011 年 4 月号最佳 C# 文章获奖作品。本中文版翻译已获原作者 Graham Wilson 首肯。 简介 本文介绍一款有趣的进度条控件&#xff08;ProgressBar&#xff09;。如下演示&#xff0c;这款名为“超赞进…

毫米波雷达:从 3D 走向 4D

1 毫米波雷达已广泛应用于汽车 ADAS 系统 汽车智能驾驶需要感知层、决策层、执行层三大核心系统的高效配合&#xff0c;其中感知层通过传感器探知周围的环境。汽车智能驾驶感知层将真实世界的视觉、物理、事件等信息转变成数字信号&#xff0c;为车辆了解周边环境、制定驾驶操…

基于OpenAI的Whisper构建的高效语音识别模型:faster-whisper

1 faster-whisper介绍 faster-whisper是基于OpenAI的Whisper模型的高效实现&#xff0c;它利用CTranslate2&#xff0c;一个专为Transformer模型设计的快速推理引擎。这种实现不仅提高了语音识别的速度&#xff0c;还优化了内存使用效率。faster-whisper的核心优势在于其能够在…

DCDC--电感的选择和影响

1、感值L的影响 1.1、纹波Ripple的影响&#xff1a;感值越大&#xff0c;纹波越小 1.2、负载瞬态响应Load Transient的影响&#xff1a;感值越大&#xff0c;负载瞬态响应越差 2、直流电阻DCR的影响 2.1、效率Efficiency的影响 相同型号&#xff0c;感值越大&#xff0c;DC…

浅学Vue3

安装 vue项目 npm init vuelatest 回车装包 npm install 路由 安装 Router npm install vue-router4 -S项目根目录新建 router --> index.js vue2中 index.jsimport Vue from vue; import VueRouter from vue-router; import Home from ../views/Home.vue;Vue.use(V…

2023年度总结:技术旅程的杨帆远航⛵

文章目录 职业规划与心灵成长 ❤️‍&#x1f525;我的最大收获与成长 &#x1f4aa;新年Flag &#x1f6a9;我的技术发展规划 ⌛对技术行业的深度思考 &#x1f914;祝愿 &#x1f307; 2023 年对我来说是一个充实而令人难以忘怀的一年。这一年&#xff0c;我在CSDN上发表了 1…

Arduino驱动VL6180X光学测距传感器(OLED显示)

Arduino驱动VL6180X光学测距传感器&#xff08;OLED显示&#xff09; 简介原理模块参数接线图代码结果 简介 VL6108X三合一光电模块&#xff0c;芯片内集成了IR VSEL(vertical-cavity surface-emitting laser)红外垂直腔面发射激光器光源、接近传感器、环境光传感器&#xff0…

Windows搭建RTMP视频流服务(Nginx服务器版)

文章目录 引言1、安装FFmpeg2、安装Nginx服务器3、实现本地视频推流服务4、使用VLC或PotPlayer可视化播放器播放视频5、RTSP / RTMP系列文章 引言 RTSP和RTMP视频流的区别 RTSP &#xff08;Real-Time Streaming Protocol&#xff09;实时流媒体协议。 RTSP定义流格式&#xff…

2023总结与展望--Empirefree

今年一篇博客都没写过了&#xff0c;好像完全在忙在工作和生活上面了&#xff0c;珍惜自我&#xff0c;保持热情&#xff0c;2024对我好点 文章目录 &#x1f525;1. 年终总结1.1.学习工作计划1.2. 生活计划1.3 个人总结 &#x1f525;2. 未来展望 &#x1f525;1. 年终总结 1…

MySQL函数、AVG | MIN | MAX | COUNT | SUM、慢查询

MySQL函数、慢查询 1、函数1.日期函数2.两个日期的时间差3.查询距离时间的间隔时间4.常用的字符串函数5.常用的数学函数6.常用的聚合函数 2、慢查询1.什么是慢查询&#xff1f; 从需求出发&#xff0c;在数据的操作过程中经常会有以下的问题&#xff1b;求和、最大值、最小值、…

未来十年,量子计算将改变物流行业

近年来&#xff0c;供应链和物流行业面临的挑战越来越多&#xff0c;从劳动力短缺到无法预测的天气以及供需变化&#xff0c;都使物流行业变得更加复杂。 因此&#xff0c;现在急需一种不同的方法来解决这些挑战&#xff0c;优化单个功能或整个业务的传统方法已无法应对这些困…

Mysql使用Mybatis进行时间操作

MySQL中支持以下日期时间类型&#xff1a; DATE&#xff1a;存储年月日&#xff08;例如&#xff1a;2023-04-05&#xff09;。范围从"1000-01-01"到"9999-12-31" TIME&#xff1a;存储时分秒&#xff08;例如&#xff1a;11:22:22&#xff09;。范围从&q…

Authing 分级管理员重磅上线,实现权限超细粒度分级管

数字化时代企业的现代化建设日益重要&#xff0c;身份权限管理系统的数字化变革已经成为企业数字化转型的核心要素之一&#xff0c;同时也对身份权限管理的“最后一公里”提出了更高的要求。管理员作为关键人员&#xff0c;往往掌握整个企业的数据核心访问权限&#xff0c;需要…