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

Java模板方法模式源码剖析及使用场景

一、原理与通俗理解

模板方法模式定义了一个算法的骨架,将某些步骤推迟到子类中实现。模板方法定义一个算法的骨架,将一些步骤的实现延迟到子类中完成。这样做的目的是确保算法的结构保持不变,同时又可以为不同的子类提供特定步骤的实现。

比如去餐馆吃饭,餐馆有固定的流程(下单->上菜->吃饭->付款),这就是模板方法。但对于不同的顾客,他们点的菜不同(重写了上菜这一步骤)。

二、案例演示

  1. 员工审核系统需求
    1. 收集员工信息
    2. 验证员工资格
    3. 核心决策是否雇佣
    4. 雇佣或拒绝员工
// 抽象类 - 模板方法
abstract class EmployeeApprover {// 模板方法public final void processRequest(EmployeeRequest request) {collectEmployeeInfo(request); // 1verifyEmployeeInfo(request); // 2if (approveEmployee(request)) { // 3hireEmployee(request); // 4} else {rejectEmployee(request); // 4}}// 收集员工信息 - 由子类实现protected abstract void collectEmployeeInfo(EmployeeRequest request);// 验证员工资格 - 由子类实现protected abstract void verifyEmployeeInfo(EmployeeRequest request);// 核心决策 - 由子类实现protected abstract boolean approveEmployee(EmployeeRequest request);// 具体雇佣步骤private void hireEmployee(EmployeeRequest request) {System.out.println("已雇佣员工: " + request.getName());}// 具体拒绝步骤private void rejectEmployee(EmployeeRequest request) {System.out.println("已拒绝员工: " + request.getName());}
}// 具体子类 - 实现抽象方法
class ITEmployeeApprover extends EmployeeApprover {@Overrideprotected void collectEmployeeInfo(EmployeeRequest request) {// 收集IT员工信息}@Overrideprotected void verifyEmployeeInfo(EmployeeRequest request) {// 验证IT员工资格}@Overrideprotected boolean approveEmployee(EmployeeRequest request) {// 审核IT员工是否合格return true;}
}
  1. CRM系统订单处理需求
    1. 收集订单信息
    2. 验证订单信息
    3. 核心决策是否发货
    4. 发货或拒绝订单
// 抽象类 - 模板方法
abstract class OrderProcessor {// 模板方法public final void processOrder(Order order) {collectOrderInfo(order); // 1verifyOrderInfo(order); // 2if (approveOrder(order)) { // 3shipOrder(order); // 4} else {rejectOrder(order); // 4}}// 收集订单信息 - 由子类实现protected abstract void collectOrderInfo(Order order);// 验证订单信息 - 由子类实现protected abstract void verifyOrderInfo(Order order);// 核心决策 - 由子类实现 protected abstract boolean approveOrder(Order order);// 具体发货步骤private void shipOrder(Order order) {System.out.println("已发货订单: " + order.getId());}// 具体拒绝步骤private void rejectOrder(Order order) {System.out.println("已拒绝订单: " + order.getId());}
}// 具体子类 - 实现抽象方法
class OnlineOrderProcessor extends OrderProcessor {@Overrideprotected void collectOrderInfo(Order order) {// 收集在线订单信息}@Overrideprotected void verifyOrderInfo(Order order) {// 验证在线订单信息}@Overrideprotected boolean approveOrder(Order order) {// 审核在线订单是否合格return true;}
}

三、Java源码中的模板方法模式

  1. InputStream抽象类

InputStream定义了读取数据的标准方法read(),而具体的读取方式由子类实现。

public abstract class InputStream implements Closeable {public abstract int read() throws IOException;public int read(byte b[]) throws IOException {return read(b, 0, b.length);}public int read(byte b[], int off, int len) throws IOException {// 模板方法}// 其他方法...
}
  1. AbstractList抽象类

AbstractList提供了模板方法addAll()用于批量添加元素,而具体的添加逻辑由子类实现。

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {public boolean addAll(Collection<? extends E> c) {// 模板方法return batchOperation(c, true);}private boolean batchOperation(...) {// ...for (E e : c)result = add(e); // 调用抽象方法}public abstract boolean add(E e); // 抽象方法,子类实现
}
  1. Spring JdbcTemplate

JdbcTemplate使用模板方法模式对底层的JDBC操作进行封装,开发者只需实现回调接口即可。以query方法为例:

public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {  public <T> T query(String sql, Object[] args, ResultSetExtractor<T> rse) throws DataAccessException {// 模板方法return query(sql, newArgPreparedStatementSetter(args), rse);}// 实际的查询逻辑private <T> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException {// 具体的数据库操作...rse.extractData(rs); // 调用回调接口}
}

四、总结优缺点以及使用经验

优点:

  1. 封装不变部分,扩展可变部分,代码复用性好
  2. 父类调用子类操作,通过子类扩展增强功能
  3. 符合开闭原则和里氏替换原则

缺点:

  1. 每个不同的实现都需要定义一个子类,类的个数可能过多
  2. 父类和子类之间存在潜在的扩展性限制
  3. 编写过程复杂,逻辑较难理解

使用经验:

  1. 适用于复杂流程,有固定不变的算法骨架和某些可变的细节
  2. 需要先分清楚算法固定部分和可变部分
  3. 体现了模板模式的核心思想"继承 + 多态"
  4. 在框架设计中是常用的模式,可以提高代码的复用性
  5. 不建议过度使用,需要权衡利弊,避免类膨胀

模板方法模式是一种典型的通过交换算法步骤扩展功能的设计模式,适用于算法骨架固定,某些步骤需要不同实现的场景。恰当使用可以提高代码复用性和系统扩展性。

相关文章:

Java模板方法模式源码剖析及使用场景

一、原理与通俗理解 模板方法模式定义了一个算法的骨架,将某些步骤推迟到子类中实现。模板方法定义一个算法的骨架,将一些步骤的实现延迟到子类中完成。这样做的目的是确保算法的结构保持不变,同时又可以为不同的子类提供特定步骤的实现。 比如去餐馆吃饭,餐馆有固定的流程(下…...

c++ 新的函数声明语法

右值引用(&&) 右值引用(&&)允许我们定义接受临时对象或移动语义的函数。 void foo(int&& x); // 右值引用参数默认参数 允许在函数声明中指定参数的默认值。 void bar(int x, double y 3.14); // 带有默认参数的函数声明noexcept关键字 指示函数…...

一款好用的AI工具——边界AICHAT

目录 一、简介二、注册及登录三、主要功能介绍3.1、模型介绍3.2、对话模型历史记录3.3、创作中心3.4、AI绘画SD3.5、文生图3.6、图生图3.7、线稿生图3.8、艺术二维码3.9、秀图广场3.10、AI绘画创作人像辅助器 一、简介 人工智能&#xff08;AI&#xff09;是一门研究、开发用于…...

谷歌承认“窃取”OpenAI模型关键信息

什么&#xff1f;谷歌成功偷家OpenAI&#xff0c;还窃取到了gpt-3.5-turbo关键信息&#xff1f;&#xff1f;&#xff1f; 是的&#xff0c;你没看错。 根据谷歌自己的说法&#xff0c;它不仅还原了OpenAI大模型的整个投影矩阵&#xff08;projection matrix&#xff09;&…...

蓝桥杯(3.10)

1219. 移动距离 import java.util.Scanner; public class Main{public static void main(String[] args) {Scanner sc new Scanner(System.in);int w sc.nextInt();int m sc.nextInt();int n sc.nextInt();m--;n--;//由从1开始变为从0开始//求行号int x1 m/w, x2 n/w;//…...

Hololens 2应用开发系列(3)——MRTK基础知识及配置文件配置(中)

Hololens 2应用开发系列&#xff08;3&#xff09;——MRTK基础知识及配置文件配置&#xff08;中&#xff09; 一、前言二、输入系统2.1 MRTK输入系统介绍2.2 输入数据提供者&#xff08;Input Data Providers&#xff09;2.3 输入动作&#xff08;Input Actions&#xff09;2…...

吴恩达深度学习笔记:深度学习引言1.1-1.5

目录 第一门课&#xff1a;神经网络和深度学习 (Neural Networks and Deep Learning)第一周&#xff1a;深度学习引言(Introduction to Deep Learning)1.1 欢迎(Welcome)1.2 什么是神经网络&#xff1f;(What is a Neural Network)1.3 神经网络的监督学习(Supervised Learning …...

【Hadoop大数据技术】——Hadoop概述与搭建环境(学习笔记)

&#x1f4d6; 前言&#xff1a;随着大数据时代的到来&#xff0c;大数据已经在金融、交通、物流等各个行业领域得到广泛应用。而Hadoop就是一个用于处理海量数据的框架&#xff0c;它既可以为海量数据提供可靠的存储&#xff1b;也可以为海量数据提供高效的处理。 目录 &#…...

蓝桥杯2023年第十四届省赛真题-工作时长

文件数据 把数据复制到excel中 数据按照增序排序 选中列数据&#xff0c;设置单元格格式&#xff0c;选择下述格式。注意&#xff0c;因为求和之后总小时数可能会超过24小时&#xff0c;所以不要选择最前面是hh的 设置B2 A2 - A1, B4 A4 - A3&#xff1b;然后选中已经算出…...

nginx禁止国外ip访问

1.安装geoip2扩展依赖 yum install libmaxminddb-devel -y 2.下载ngx_http_geoip2_module模块 https://github.com/leev/ngx_http_geoip2_module.git 3.编译安装 ./configure --add-module/datasdb/ngx_http_geoip2_module-3.4 4.下载最新数据库文件 模块安装成功后,还要…...

《腾讯音乐》24校招Java后端一面面经

1.手写LRU 2.项目拷打 3.Https客户端校验证书的细节&#xff1f; 4.对称加密和非对称加密的区别&#xff1f;你分别了解哪些算法&#xff1f; 5.在信息传输过程中&#xff0c;Https用的是对称加密还是非对称加密&#xff1f; 6.怎么防止下载的文件被劫持和篡改&#xff1f; 7.H…...

JavaScript:ES至今发展史简说

ECMAScript&#xff08;简称ES&#xff09;是JavaScript的标准&#xff0c;它的发展史经历了多个版本的迭代&#xff0c;以下是主要里程碑&#xff1a; ES1 (1997年6月)&#xff1a;首个正式发布的ECMAScript标准&#xff0c;基于当时的JavaScript&#xff08;由Netscape公司开…...

Linux:进程

进程 知识铺垫冯诺依曼体系结构操作系统&#xff08;OS&#xff09; 进程概念进程的查看ps 命令获取进程 pid文件内查看进程终止进程的方式kill命令快捷键 进程的创建 forkfork 返回值问题 进程状态运行状态 &#xff1a;R休眠状态&#xff1a;S &#xff08;可中断&#xff09…...

【Vue3】defineExpose 实践

【Vue3】defineExpose 实践 defineExpose 是 Vue 3 的 <script setup> 语法糖中提供的一个函数&#xff0c;用于显式地暴露组件的属性、方法或其他响应式状态给其父组件或外部使用。这是在使用 <script setup> 语法时&#xff0c;控制组件公开哪些内部状态和方法的…...

centos7.9安装nacos

centos7.9安装nacos2.3.1 在centos x86_64环境安装nacos2.31环境准备 jdk1.8 、 mysql、 nacos 在window11环境安装nacos2.31 在centos x86_64环境安装nacos2.31 环境准备 jdk1.8 、 mysql、 nacos Nacos 依赖 Java 环境来运行。我们通过下载编译后压缩包方式安装。 重点踩坑…...

ARM/Linux嵌入式面经(四):浙江大华

大华一面 嵌入式 主要是问的项目相关 标准的十五分钟 电话面 这个面试官主要问项目,我同门面的全问八股,可能面试官不一样吧 文章目录 UART串口通信的波特率,常用波特率有哪些串口通信校验方式是什么,有什么区别方便简单的奇偶校验偶校验(even parity)累加和校验CRC循环冗…...

ubuntu 18.04安装教程(详细有效)

文章目录 一、下载ubuntu 18.04镜像二、安装ubuntu1. 点击下载好的Vmware Workstation&#xff0c;点击新建虚拟机&#xff0c;选择 “自定义(高级)”&#xff0c;之后下一步。2. 默认配置&#xff0c;不需要更改&#xff0c;点击下一步。3. 选择 “安装程序光盘映像文件(iso)(…...

第二十一天-NumPy

目录 什么是NumPy NumPy使用 1.数组的创建 2.类型转换 3.赠删改查 4.数组运算 5.矩阵运算 什么是NumPy 1.NumPy操作的是多维数组&#xff0c;什么是纬度&#xff1f; NumPy使用 1. 安装 pip install numpy import numpy as np 2.官网&#xff1a; 中文官网&#xff1a…...

Vue:自动按需导入element-plus图标

自动导入使用 unplugin-icons 和 unplugin-auto-import 从 iconify 中自动导入任何图标集。 完整vite.config.js参考模板 https://download.csdn.net/download/ruancexiaoming/88928539 动态导入图标参考 https://blog.csdn.net/ruancexiaoming/article/details/136568219 导入…...

魔法之线:探索string类的神秘世界

&#x1f389;个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名乐于分享在学习道路上收获的大二在校生 &#x1f648;个人主页&#x1f389;&#xff1a;GOTXX &#x1f43c;个人WeChat&#xff1a;ILXOXVJE &#x1f43c;本文由GOTXX原创&#xff0c;首发CSDN&…...

突破平台壁垒:3种方法让Windows直接运行安卓应用

突破平台壁垒&#xff1a;3种方法让Windows直接运行安卓应用 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 当你在电脑前急需使用手机专属办公软件&#xff0c;却只能…...

PowerToys MeasureTool:让屏幕测量变得如此简单,设计师必备的免费神器

PowerToys MeasureTool&#xff1a;让屏幕测量变得如此简单&#xff0c;设计师必备的免费神器 【免费下载链接】PowerToys Microsoft PowerToys is a collection of utilities that supercharge productivity and customization on Windows 项目地址: https://gitcode.com/Gi…...

智能去重引擎:Zotero文献管理效率提升指南

智能去重引擎&#xff1a;Zotero文献管理效率提升指南 【免费下载链接】ZoteroDuplicatesMerger A zotero plugin to automatically merge duplicate items 项目地址: https://gitcode.com/gh_mirrors/zo/ZoteroDuplicatesMerger 学术研究中&#xff0c;文献库的整洁度直…...

LeetDown:macOS上最简单快速的A6/A7设备降级工具终极指南

LeetDown&#xff1a;macOS上最简单快速的A6/A7设备降级工具终极指南 【免费下载链接】LeetDown a GUI macOS Downgrade Tool for A6 and A7 iDevices 项目地址: https://gitcode.com/gh_mirrors/le/LeetDown 还在为老款iPhone或iPad升级后卡顿而烦恼吗&#xff1f;Leet…...

DeepMosaics:智能处理隐私保护的开源工具全面解析

DeepMosaics&#xff1a;智能处理隐私保护的开源工具全面解析 【免费下载链接】DeepMosaics Automatically remove the mosaics in images and videos, or add mosaics to them. 项目地址: https://gitcode.com/gh_mirrors/de/DeepMosaics 在当今数字化时代&#xff0c;…...

QEMU v8.2.4 源码深度剖析:从编译到核心模块的实战指南

1. 从零开始&#xff1a;编译属于你自己的QEMU v8.2.4 如果你和我一样&#xff0c;对虚拟化技术充满好奇&#xff0c;总想扒开QEMU这头“巨兽”的肚子看看里面到底是怎么运转的&#xff0c;那么从源码编译开始&#xff0c;绝对是最扎实的第一步。这不仅仅是得到一个可执行文件&…...

编写程序让智能文具收纳盒检测物品缺失,常用笔不在时提示“寻找放回”。

项目名称&#xff1a;PenPal Guardian (智能文具收纳盒)一、 实际应用场景描述场景设定为一个带有重量感应和RFID识别功能的智能文具收纳盒。在这个场景中&#xff0c;收纳盒被放置在办公桌的固定位置。盒子里预先放置了“必备三件套”&#xff1a;一支签字笔、一支铅笔、一把尺…...

OpenClaw+Qwen3-14B数据安全方案:敏感文件本地自动化处理

OpenClawQwen3-14B数据安全方案&#xff1a;敏感文件本地自动化处理 1. 为什么需要本地化的数据安全方案 去年我在处理公司季度财报时遇到一个棘手问题&#xff1a;需要将几十份PDF报表中的关键数据提取出来做交叉分析&#xff0c;但内容涉及商业机密&#xff0c;不敢直接上传…...

Chrome-Charset扩展深度解析:编码检测与Manifest V3架构实战指南

Chrome-Charset扩展深度解析&#xff1a;编码检测与Manifest V3架构实战指南 【免费下载链接】Chrome-Charset An extension used to modify the page default encoding for Chromium 55 based browsers. 项目地址: https://gitcode.com/gh_mirrors/ch/Chrome-Charset C…...

#CSDN博客-智能客服RAG实战

基于 Milvus Ollama(BGE-M3) DeepSeek 的智能客服 RAG 实战 一、项目背景 在社保、医保、就业等公共服务领域&#xff0c;每天都有大量群众拨打热线咨询相似问题。传统人工客服成本高、效率低&#xff0c;而基于关键词匹配的机器人又难以理解用户的真实意图。 本项目基于 …...