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

提升代码重用性:模板设计模式在实际项目中的应用

在软件开发中,我们经常面临着相似的问题,需要使用相同的解决方法。当我们希望将这种通用的解决方法抽象出来,并在不同的情境中重复使用时,就可以使用设计模式中的模板模式(Template Pattern)。模板模式是一种行为型模式,它定义了一个抽象类或接口,其中包含了一个算法框架,而具体的实现细节则由子类来完成。

模板模式的结构

模板模式由以下几个组成部分:

  • 抽象类(Abstract Class):抽象类定义了一个模板方法,该方法包含了一个算法的框架,而具体的实现细节则由子类来完成。抽象类可能还包含其他的公共方法和钩子方法,用于被子类调用或覆盖。
  • 具体类(Concrete Class):具体类是抽象类的子类,负责实现抽象类中的抽象方法。每个具体类都可以根据自身的需求来实现这些方法,从而完成算法的具体步骤。

模板模式的工作原理

模板模式基于"封装变化"的原则,通过将不变的算法框架放在抽象类中,将可变的实现细节留给具体类来实现。这样一来,我们可以在不改变整体结构的情况下,更容易地扩展和修改算法的部分细节。

当使用模板模式时,通常会按照以下步骤进行:

  1. 定义一个抽象类,并在其中定义一个模板方法,该方法包含了算法框架的基本流程。
  2. 在抽象类中定义一个或多个抽象方法,用于被子类实现。这些抽象方法代表了算法中可变的部分。
  3. 创建具体类,继承自抽象类,并实现其中的抽象方法。每个具体类可以根据自身的需求来实现这些方法,从而完成算法的具体步骤。
  4. 在客户端代码中,通过调用抽象类的模板方法来触发算法的执行。

模板模式的应用场景

模板模式在许多不同的应用场景中都有广泛的应用。下面列举一些常见的应用场景:

  1. 算法骨架:当多个类拥有相同的算法框架,只有部分步骤有所不同时,可以使用模板模式将这些不同的部分抽象出来。例如,在游戏开发中,不同种类的敌人可能有不同的行为模式,但它们都共享相同的攻击和移动逻辑。通过使用模板模式,可以将共享的逻辑放在基类中,而将特定的行为留给子类实现。
  2. 生命周期钩子:当希望控制算法执行顺序,并在某些步骤上留下扩展点时,可以使用模板模式。例如,在软件开发中,我们可能需要定义一个对象的创建或销毁过程,并允许子类在适当的时候插入自己的逻辑。模板模式可以提供这种灵活性,同时保持整体算法的一致性。
  3. 框架设计:模板模式在框架设计中也非常有用。框架通常定义了一系列的抽象方法或接口,供开发者根据自己的需求来实现。框架本身会提供一个算法框架,其中包含了一些公共的处理逻辑。开发者可以通过继承框架中的抽象类或接口,并实现其中的方法来定制自己的功能。
  4. 流程控制:模板模式也可用于流程控制方面。例如,在工作流系统中,每个步骤都有固定的执行顺序,并且可能涉及到一些共享的处理逻辑。通过使用模板模式,可以定义一个基本的流程,然后针对不同的步骤实现具体的行为。
  5. 数据库操作:在数据库相关的操作中,常常需要进行连接、查询和关闭等步骤。这些步骤可以被抽象出来作为模板方法,而具体的查询和处理细节则由子类来实现。

以订单处理的流程控制为例

// 抽象类
abstract class OrderProcessor {public void processOrder() {if (validateOrder()) {prepareOrder();if (shouldNotifyCustomer()) {notifyCustomer();}shipOrder();} else {handleInvalidOrder();}}protected abstract boolean validateOrder();protected abstract void prepareOrder();protected abstract void notifyCustomer();protected abstract void shipOrder();// 钩子方法protected boolean shouldNotifyCustomer() {return true;}protected void handleInvalidOrder() {System.out.println("Invalid order, unable to process.");}
}// 具体类实现订单处理流程
class OnlineOrderProcessor extends OrderProcessor {private String orderNumber;public OnlineOrderProcessor(String orderNumber) {this.orderNumber = orderNumber;}@Overrideprotected boolean validateOrder() {System.out.println("Validating online order: " + orderNumber);// 实际的验证逻辑return true;}@Overrideprotected void prepareOrder() {System.out.println("Preparing online order: " + orderNumber);// 实际的准备逻辑}@Overrideprotected void notifyCustomer() {System.out.println("Notifying customer about online order: " + orderNumber);// 实际的通知逻辑}@Overrideprotected void shipOrder() {System.out.println("Shipping online order: " + orderNumber);// 实际的发货逻辑}
}// 客户端代码
public class Client {public static void main(String[] args) {OrderProcessor orderProcessor = new OnlineOrderProcessor("12345");orderProcessor.processOrder();}
}

在上述示例代码中,抽象类 OrderProcessor 定义了一个处理订单的模板方法 processOrder(),并包含了一系列的具体步骤。具体类 OnlineOrderProcessor 继承自抽象类,并实现了其中的抽象方法,根据具体需求实现了验证、准备、通知和发货的逻辑。客户端代码创建了一个具体的订单处理器并调用 processOrder() 方法来触发订单处理流程。

不同的实现类具有相同的模板方法,但是具体实现可以根据实际需求进行定制,既保证了模板方法的重用,又具备了灵活性。

运行以上代码将输出以下内容:

Validating online order: 12345
Preparing online order: 12345
Notifying customer about online order: 12345
Shipping online order: 12345

总结

模板模式是一种通过封装算法框架和提供可变的实现细节,来实现代码重用的设计模式。它能够简化代码的编写和维护,并且使得系统更易于扩展和修改。通过合理地使用模板模式,我们可以将通用的解决方法抽象出来,提高开发效率,减少重复代码的出现。

相关文章:

提升代码重用性:模板设计模式在实际项目中的应用

在软件开发中,我们经常面临着相似的问题,需要使用相同的解决方法。当我们希望将这种通用的解决方法抽象出来,并在不同的情境中重复使用时,就可以使用设计模式中的模板模式(Template Pattern)。模板模式是一…...

11-k8s-service网络

文章目录 一、网络相关资源介绍二、开启ipvs三、nginx网络示例四、pod之间的访问示例五、service反向代理示例 一、网络相关资源介绍 Servcie介绍 Service是对一组提供相同功能的Pods的抽象,并为它们提供一个统一的入口。借助Service,应用可以方便的实现…...

MyBatisPlus(二十二)代码生成器

使用场景 使用代码生成器&#xff0c;根据数据库表&#xff0c;自动生成对应的 Entity&#xff0c;Mapper&#xff0c;Service&#xff0c;Controller 。 代码 依赖 两个依赖&#xff1a; 生成器依赖模板依赖 <dependency><groupId>com.baomidou</groupId&…...

git报错The project you were looking for could not be found 解决方式

问题描述&#xff1a; 使用git从远程仓库克隆项目到本地的时候。 git clone http://gitlab.com/project/xxxx.git出现这个问题&#xff1a;The project you were looking for could not be found. 原因分析&#xff1a; 你的账号没有项目的权限&#xff0c;你可以在浏览器输…...

“编辑微信小程序与后台数据交互与微信小程序wxs的使用“

引言 在现代移动应用开发中&#xff0c;微信小程序已经成为了一个非常流行和广泛使用的平台。为了使小程序能够展示丰富的内容和实现复杂的功能&#xff0c;与后台数据的交互是至关重要的。同时&#xff0c;微信小程序还提供了一种特殊的脚本语言——wxs&#xff0c;用于增强小…...

从Linux的tty_struct指针获取驱动上下文

背景 问题 前段时间开发一个tty驱动&#xff0c;用途是实现仪器对GPIB消息的接收、处理和上报。对于上报场景&#xff0c;下位机应用将上报内容写入一个驱动创建的tty设备&#xff0c;tty子系统将应用的输入转发给tty驱动&#xff0c;tty驱动将其转换成对SPI从设备&#xff0…...

PHP WAP餐厅点餐系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP餐厅点餐系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 PHP WAP餐厅点餐系统 代码 https://download.csdn.net/download/qq_41221322/88440001 二、…...

智慧公厕改变城市生活,厕所革命标杆应用解决方案

随着城市化进程的加快&#xff0c;公厕作为城市基础设施的重要组成部分&#xff0c;扮演着不可忽视的角色。然而&#xff0c;传统的公厕粗放型管理模式&#xff0c;已经无法满足市民日益增长的需求。为了提升公厕的管理和服务水平&#xff0c;智慧公厕应运而生。 什么是智慧公…...

YOLOv5改进实战 | 更换主干网络Backbone(四)之轻量化模型MobileNetV3

前言 轻量化网络设计是一种针对移动设备等资源受限环境的深度学习模型设计方法。下面是一些常见的轻量化网络设计方法: 网络剪枝:移除神经网络中冗余的连接和参数,以达到模型压缩和加速的目的。分组卷积:将卷积操作分解为若干个较小的卷积操作,并将它们分别作用于输入的不…...

上新啦!请查收云原生虚拟数仓 PieCloudDB 十月动态

PieCloudDB Database 最新动态 PieCloudDB 压缩效率得到提升 为了节省存储空间&#xff0c;降低用户存储费用&#xff0c;PieCloudDB 在压缩率上不断优化&#xff0c;包括&#xff1a; 对 HLL&#xff08;HyperLogLog&#xff09;支持游程编码&#xff08;Run Length Encodi…...

第五章:Python中的集合(上)

Python中的集合 是一组不可重复元素的无序集合。集合通常用于在其中执行成员测试,删除重复项,计算交集、并集和差集等操作。 Python的集合是可迭代对象。具体来说,集合可以通过for循环逐个访问其中的元素。同时,集合还支持一些迭代器相关的方法,例如iter()函数和next()函…...

虚拟机灾备建设中NFS存储直接访问技术应用

NFS&#xff08;Network File System&#xff09;是一种网络文件系统&#xff0c;允许不同计算机之间共享文件和目录。在Linux系统中&#xff0c;可以使用NFS协议来访问网络存储。 当新服务器硬盘不足时&#xff0c;旧的服务器硬盘容量大&#xff0c;不拔硬盘的情况下&#xf…...

java业务开发常用的配置表及代码

配置表 通过配置表&#xff0c;灵活的配置。 开发中某些经常变更的参数值&#xff0c;加上配置。比如 订单30分钟后失效&#xff0c;需求变更&#xff0c;要改为15分钟&#xff0c;那么直接改配置表就行了&#xff0c;不用发版。 某些关键的容易出错的逻辑&#xff0c;加上一…...

安装Homebrew安装Git(Mac)

使用Homebrew安装Git&#xff08;Mac&#xff09; 1 安装Xcode 安装Homebrew之前&#xff0c;需要安装Xcode Comand Line Tools&#xff1a; xcode-select --install 2 安装Homebrew /usr/bin/ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/mas…...

[云原生1.] Docker容器的简单介绍和基本管理

文章目录 1. Docker容器的基本概述1.1 简介1.2 容器的优点1.3 Docker与虚拟机的区别1.4 Docker核心组成1.4.1 镜像1.4.2 容器1.4.3 仓库 1.5 容器在内核中支持2种重要技术1.5.1 linux六大namespace&#xff08;命名空间&#xff09; 1.6 Docker的使用场景 2. Docker的部署2.1 前…...

JSR303数据校验

Component //注册bean ConfigurationProperties(prefix "person") Validated //数据校验 public class Person { Email(message"邮箱格式错误") //name必须是邮箱格式 private String name; } 使用数据校验&#xff0c;可以保证数据的正确性&#xff01;…...

JavaCV + FFmpeg 播放音视频

JavaCV FFmpeg 播放音视频 1、导入JavaCV库1.1 使用ffmpeg必要库1.2 简单FFmpeg命令 待续~~~~ FFmpeg documentation bytedeco/javacv - GitHub 1、导入JavaCV库 gradle下面这种会导入javacv-platform所有包&#xff0c;非常耗时&#xff1a;https://repo.maven.apache.org/…...

万能DIY预约小程序源码系统 上门预约服务小程序搭建 适用于各种预约场景 自由DIY功能模块

在这个快节奏的时代&#xff0c;预约服务已经成为了我们日常生活的一部分。从看病挂号到餐厅预订&#xff0c;从美发美容到家政服务&#xff0c;预约已经深入到了各个领域。然而&#xff0c;传统的预约方式存在着许多不便&#xff0c;如电话预约、在线填写表格等&#xff0c;不…...

边缘检测算法

边缘检测算法是在数字图像处理中常用的一种技术&#xff0c;用于检测图像中物体边缘的位置。以下是几种常见的边缘检测算法&#xff1a; Sobel算子&#xff1a;Sobel算子是一种基于梯度的算法&#xff0c;通过计算图像的水平和垂直方向的梯度值&#xff0c;并将其组合起来得到边…...

数据结构与算法-树

树 &#x1f388;1.树和二叉树&#x1f388;2.树&#x1f52d;2.1树的定义&#x1f52d;2.2树的4种表示方法&#x1f52d;2.3树的基本术语&#x1f52d;2.4树的抽象数据类型定义 &#x1f388;3.二叉树&#x1f52d;3.1二叉树的定义&#x1f52d;3.2二叉树的抽象数据类型定义&a…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...