掌握java模板方法模式,提升代码复用与扩展的艺术

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

  • 算法骨架固定:如果一个算法的基本结构已经固定,但具体的实现步骤可能因为不同的场景而不同,这个时候可以使用模板方法模式。
  • 实现代码复用:如果有多个类的某些方法结构相似,但是实现细节不同,这个时候可以将这些相同的结构抽象到父类中,由子类来实现不同的细节。
  • 简化代码实现:模板方法模式可以将复杂的代码实现分离成几个简单的步骤,从而降低代码实现的难度和复杂度。
  • 框架和库的设计:模板方法模式是设计框架和库的重要方式之一,它可以提供统一的接口和标准的实现流程,方便用户进行扩展和定制

代码示例

AbstractClass 是一个抽象类,它定义了算法的骨架,其中 templateMethod() 是模板方法,它定义了算法的流程,由一些抽象方法 primitiveOperation1() 和 primitiveOperation2() 组成。
  ConcreteClass 是 AbstractClass 的具体子类,它实现了抽象方法,定义了具体的算法细节。在客户端使用时,创建 ConcreteClass ,然后调用其 templateMethod() 方法,即可完成算法的执行。
代码示例如下:
抽象类,定义算法骨架:

public abstract class AbstractClass {// 模板方法,定义算法流程public final void templateMethod() {primitiveOperation1();primitiveOperation2();}// 抽象方法1,由子类实现public abstract void primitiveOperation1();// 抽象方法2,由子类实现public abstract void primitiveOperation2();
}

具体子类,实现具体的算法细节:


public class ConcreteClass extends AbstractClass {@Overridepublic void primitiveOperation1() {System.out.println("ConcreteClass.primitiveOperation1()");}@Overridepublic void primitiveOperation2() {System.out.println("ConcreteClass.primitiveOperation2()");}
}

客户端使用:

public class Client {public static void main(String[] args) {AbstractClass abstractClass = new ConcreteClass();abstractClass.templateMethod();}
}

需要注意的是,在模板方法模式中,模板方法通常被声明为 final,以防止子类对其进行重写。同时,由于模板方法是一个抽象方法,因此在实现时需要注意不同抽象方法的实现顺序,以确保算法的正确性。

Spring 中的 JdbcTemplate

  1. 在 JdbcTemplate 类中,定义一个 execute 方法,该方法接收一个 ConnectionCallback 或 StatementCallback 对象作为参数。这些回调对象实现了具体的数据库操作逻辑。
  2. 在 execute 方法中,根据传入的回调对象类型,创建相应的 PreparedStatement 或 Statement 对象,并调用回调对象的 doInConnection 或 doInStatement 方法执行具体的数据库操作。
  3. 将数据库连接、PreparedStatement 或 Statement 对象等资源关闭的操作封装在 finally 代码块中,确保资源能够被正确释放。
    代码如下:
public <T> T execute(ConnectionCallback<T> action) throws DataAccessException {Assert.notNull(action, "Callback object must not be null");Connection con = DataSourceUtils.getConnection(obtainDataSource());try {Connection conToUse = createConnectionProxy(con);return action.doInConnection(conToUse);}catch (SQLException ex) {String sql = getSql(action);DataSourceUtils.releaseConnection(con, getDataSource());con = null;throw translateException("ConnectionCallback", sql, ex);}finally {DataSourceUtils.releaseConnection(con, getDataSource());}}

JdbcTemplate 类的 execute 方法接收一个 ConnectionCallback 对象作为参数,然后根据该对象执行具体的数据库操作。这样,JdbcTemplate 就实现了模板模式,将数据库操作的具体逻辑封装在 ConnectionCallback 对象中,而 JdbcTemplate 只负责管理数据库连接和资源释放。

优点

  • 代码复用性:模板模式通过将类的共同部分代码抽象出来放在父类中,使得子类只需要实现差异部分,这大大减少了子类的重复代码。
  • 可扩展性:当需要新增功能时,可以通过子类来实现扩展,而不需要改动原有的代码和代码框架,这符合软件设计的“开闭原则”,即对扩展开放,对修改封闭。
  • 灵活性:所有子类实现的是同一套算法模型,在使用模板的地方,可以通过切换不同的子类来实不同的功能,这符合“里氏替换原则”。
  • 维护性:由于模板模式的行为由父类控制,子类实现,这样的结构清晰,有利于维护。

缺点

  • 复杂性:对于一些简单的任务,使用模板模式可能会引入不必要的复杂性。
  • 继承的限制:模板模式基于继承,这意味着它可能不适用于所有的编程语言或框架,特别是那些不支持继承的语言或框架。
  • 设计习惯:我们平常的设计习惯可能更偏向于直接实现功能,而不是先定义一个模板方法,这可能需要一定的适应时间。

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

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

相关文章

跨专业考研难度大吗?听听过来人的真实经历

在考研的大潮中&#xff0c;跨专业考研成为了一个不可忽视的现象。许多考生因为对原专业失去兴趣、追求职业梦想或其他原因&#xff0c;选择了跨专业报考。那么&#xff0c;跨专业考研的难度究竟有多大呢&#xff1f;今天&#xff0c;我们就来聊聊这个话题&#xff0c;听听过来…

不是我吹,这8道HashMap面试题让你面试时对答如流

前言 又到了一年一度的金三银四面试季&#xff0c;我们拿着自己的面试秘籍去面试&#xff0c;但是面试官的问题五花八门&#xff0c;让我们摸不清他们的套路。今天我就总结了面试时必问的hashmap面试题&#xff0c;无论面试官怎么问&#xff0c;我们都对答如流。 另外本人整理了…

java小记(2)

IS-A&#xff1a;类的父子继承关系。 default&#xff1a;关键字&#xff0c;与Java中的public&#xff0c;private等关键字一样&#xff0c;都属于修饰符关键字&#xff0c;可以用来修饰属性、方法以及类&#xff0c;但是default一般用来修饰接口中的方法。 接口与抽象类的区…

代码随想录算法训练营第二十四天 | 77. 组合

回溯算法理论基础 https://programmercarl.com/%E5%9B%9E%E6%BA%AF%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。 回溯是递归的副产品&#xff0c;只要有递归就会有回溯。 回溯法并不是什么高效的…

马斯克正式起诉OpenAI和奥特曼!

就在刚刚&#xff0c;马斯克闹出来一件大事——正式起诉OpenAI和Sam Altman&#xff0c;并要求OpenAI 恢复开源GPT-4等模型&#xff01; 众所周知&#xff0c;马斯克这两年一只在推特上指责 OpenAI是CloseAI(不开源)&#xff0c;但都只是停留在口头上。 而这次马斯克动了真格。…

nginx if 指令

目录 nginx if 指令直接判断变量判断是否等于字符串判断变量是否匹配正则表达式文件及目录判断示例1&#xff1a;判断index.html是否存在示例2&#xff1a;判断URL中是否存在某个参数Parameter示例3&#xff1a;判断URI中是否为某个特定路径示例4&#xff1a;开放白名单内的功能…

从0开始python学习-53.python中flask创建简单接口

目录 1. 创建一个简单的请求,没有写方法时默认为get 2. 创建一个get请求 3. 创建一个post请求&#xff0c;默认可以使用params和表单传参 4. 带有参数的post请求 1. 创建一个简单的请求,没有写方法时默认为get from flask import Flask, request# 初始化一个flask的对象 ap…

RK3566 linux iperf网络测试

一、开发环境 系统:buildroot&#xff1b; 在Linux目标板和Windows PC上运行iperf进行测试&#xff1b; 二、调试 1、查询目标板上的iperf 使用终端助手连接目标板&#xff0c;然后输入命令查询iperf的版本&#xff1a; rootrk3566-buildroot:~# iperf -v iperf version …

图数据库 之 Neo4j - 应用场景3 - 知识图谱(8)

背景 知识图谱的复杂性:知识图谱通常包含大量的实体、关系和属性,以及它们之间的复杂关联。传统的关系型数据库在处理这种复杂性时可能面临性能和灵活性的挑战。 图数据库的优势:图数据库是一种专门用于存储和处理图结构数据的数据库。它们使用节点和边来表示实体和关系,并…

USB - Battery Charing

Getting to the bottom of USB Battery Charging (了解 USB 电池充电的真相) 如今&#xff0c;几乎所有带电池的产品都被期望支持 BC1.2 USB 充电标准。 Today, almost every product with a battery is expected to support the BC1.2 standard for USB charging. 这对消费者来…

详解字符串函数<string.h>(上)

1. strlen函数的使用和模拟实现 size_t strlen(const char* str); 1.1 函数功能以及用法 字符串长度 strlen函数的功能是计算字符串的长度。在使用时&#xff0c;要求用户传入需要计算长度的字符串的起始位置&#xff0c;并返回字符串的长度。 #include <stdio.h> #…

基于SSM医院电子病历管理系统的设计与实现(源代码+数据库脚本+万字文档+PPT)

系统介绍 医院电子病历管理系统主要是借助计算机&#xff0c;通过对医院电子病历管理系统所需的信息管理&#xff0c;增加用户的选择&#xff0c;同时也方便对广大用户信息的及时查询、修改以及对用户信息的及时了解。医院电子病历管理系统 对用户带来了更多的便利&#xff0c…

Python GUI自动化定位代码参考

一、pyautogui原始逻辑 import pyautogui # 获取指定图片在屏幕上的位置 image_path path/to/image.png target_position pyautogui.locateCenterOnScreen(image_path) if target_position is not None: # 获取偏移量 offset_x 10 offset_y 10 # 计算实际点…

一文读懂ZKFair PFP-CyberArmy的参与价值与潜力

3月2日&#xff0c;ZKFair PFP-CyberArmy 将在 Element 上正式开始Public Sale。

文件基础和文件fd

文章目录 预备知识C语言的文件接口系统调用文件fd 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站。 预备知识 我们平时说文件就是说文件里…

1_Springboot(一)入门

Springboot&#xff08;一&#xff09;——入门 本章重点&#xff1a; 1.什么是Springboot; 2.使用Springboot搭建web项目&#xff1b; 一、Springboot 1.Springboot产生的背景 Servlet->Struts2->Spring->SpringMVC&#xff0c;技术发展过程中&#xff0c;对使…

大模型量化技术原理-SmoothQuant

近年来&#xff0c;随着Transformer、MOE架构的提出&#xff0c;使得深度学习模型轻松突破上万亿规模参数&#xff0c;从而导致模型变得越来越大&#xff0c;因此&#xff0c;我们需要一些大模型压缩技术来降低模型部署的成本&#xff0c;并提升模型的推理性能。 模型压缩主要分…

强化学习(六)时序差分

时序差分&#xff08;TD&#xff09;是强化学习的核心&#xff0c;其是蒙特卡罗&#xff08;MC&#xff09;和动态规划&#xff08;DP&#xff09;的结合。 1、TD 预测 TD 和 MC 都是利用经验来解决预测问题。一种非平稳环境的一般访问蒙特卡罗方法是 V ( S t ) ← V ( S t …

Python GUI开发库之nicegui使用详解

概要 在 Python 中,创建图形用户界面(GUI)应用程序通常需要大量的代码和时间。然而,随着 Python 生态系统的不断发展,出现了一些简化 GUI 开发过程的工具和库。其中之一就是 NiceGUI 库。本文将深入探讨 NiceGUI 库的功能、用法以及如何利用它来创建漂亮而功能丰富的 GUI…

如何使用css实现一个加载动画

如何使用css实现一个加载动画 有四个点 初始化为同一个颜色 每个阶段 不同的透明度 刷新也不会影响初始化 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthd…