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

设计模式 - 行为模式_Template Method Pattern模板方法模式在数据处理中的应用

文章目录

  • 概述
  • 1. 核心思想
  • 2. 结构
  • 3. 示例代码
  • 4. 优点
  • 5. 缺点
  • 6. 适用场景
  • 7. 案例:模板方法模式在数据处理中的应用
    • 案例背景
    • UML
    • 搭建抽象基类 - 数据处理的 “总指挥”
    • 子类定制 - 适配不同供应商
      • 供应商 A 的数据处理器
      • 供应商 B 的数据处理器
    • 在业务代码中整合运用
  • 8. 总结

在这里插入图片描述


概述

模板方法模式(Template Method Pattern)是一种行为设计模式,其核心思想是:定义一个操作的算法骨架,将一些步骤的实现延迟到子类中。在软件设计中,模板方法模式通常用于处理一系列相似的操作,这些操作可以被抽象为固定的流程,而流程中的某些步骤则由子类来具体实现。


1. 核心思想

模板方法模式的核心思想可以总结为以下几点:

  • 固定流程:定义一个固定的算法流程,确保所有子类都遵循相同的步骤。
  • 可变步骤:将某些步骤的具体实现延迟到子类中,允许子类根据需求定制。
  • 代码复用:通过将通用逻辑放在父类中,减少代码重复。

2. 结构

模板方法模式通常由以下几个部分组成:

  1. 抽象类(Abstract Class):定义算法的骨架,并包含一些抽象方法供子类实现。
  2. 具体子类(Concrete Class):实现抽象类中的抽象方法,完成具体的业务逻辑。
  3. 模板方法(Template Method):在抽象类中定义的一个方法,它调用了算法中的各个步骤。

3. 示例代码

一个简单的模板方法模式示例,展示如何定义一个算法骨架并在子类中实现具体步骤。

// 抽象类
abstract class AbstractClass {// 模板方法,定义了算法的骨架public final void templateMethod() {step1();step2();step3();}// 具体方法,子类可以直接使用private void step1() {System.out.println("执行步骤1");}// 抽象方法,子类需要实现protected abstract void step2();// 钩子方法,子类可以选择性重写protected void step3() {System.out.println("执行步骤3");}
}// 具体子类A
class ConcreteClassA extends AbstractClass {@Overrideprotected void step2() {System.out.println("ConcreteClassA 执行步骤2");}
}// 具体子类B
class ConcreteClassB extends AbstractClass {@Overrideprotected void step2() {System.out.println("ConcreteClassB 执行步骤2");}@Overrideprotected void step3() {System.out.println("ConcreteClassB 执行步骤3");}
}// 客户端代码
public class TemplateMethodPatternDemo {public static void main(String[] args) {AbstractClass classA = new ConcreteClassA();classA.templateMethod();AbstractClass classB = new ConcreteClassB();classB.templateMethod();}
}

为了防止恶意修改,模板方法通常使用final关键字修饰,避免被子类重写。


4. 优点

  • 代码复用:通过将通用逻辑放在父类中,减少了代码重复。
  • 扩展性:子类可以通过实现抽象方法来扩展算法的某些步骤,而无需修改算法的整体结构。
  • 灵活性:钩子方法(Hook Method)允许子类选择性地覆盖某些步骤,增加了灵活性。

5. 缺点

  • 复杂性:如果算法的步骤过多,可能会导致类的层次结构变得复杂。
  • 限制性:模板方法模式要求算法的步骤是固定的,这可能会限制某些场景下的灵活性。

6. 适用场景

  • 固定流程:当某个算法的流程是固定的,但某些步骤的具体实现可能不同时,可以使用模板方法模式。
  • 代码复用:当多个子类有共同的逻辑时,可以将这些逻辑提取到父类中,减少代码重复。
  • 框架设计:在框架设计中,模板方法模式常用于定义框架的核心流程,而将具体实现留给用户自定义。

7. 案例:模板方法模式在数据处理中的应用

案例背景

我们的平台需要处理来自以下两个供应商的商品数据:

  1. 供应商 A:提供 JSON 格式的商品数据,需要对商品名称进行标准化处理。
  2. 供应商 B:提供 XML 格式的商品数据,需要对商品价格进行汇率转换。

尽管数据格式和处理逻辑不同,但整体的处理流程是相同的,包括以下步骤:

  1. 数据验证:验证数据的完整性和合法性。
  2. 数据解析:将原始数据解析为内部数据结构。
  3. 数据处理:根据业务需求对数据进行处理。
  4. 数据存储:将处理后的数据存储到数据库中。

UML

在这里插入图片描述

搭建抽象基类 - 数据处理的 “总指挥”

首先,我们创建一个抽象的基类 AbstractProductDataHandler,它将定义整个数据处理流程的骨架。

public abstract class AbstractProductDataHandler {// 模板方法,定义了数据处理的固定流程public final void handleProductData(String rawData) {if (validateData(rawData)) {logStart(rawData);Product product = parseData(rawData);processProduct(product);saveProduct(product);logCompletion(product);} else {handleValidationFailure(rawData);}}// 抽象方法,子类需要实现数据验证逻辑protected abstract boolean validateData(String rawData);// 抽象方法,子类需要实现数据解析逻辑protected abstract Product parseData(String rawData);// 抽象方法,子类需要实现数据处理逻辑protected abstract void processProduct(Product product);// 具体方法,通用的数据存储逻辑private void saveProduct(Product product) {System.out.println("保存商品数据:" + product);// 实际项目中,这里会调用数据库操作}// 具体方法,记录处理开始日志private void logStart(String rawData) {System.out.println("开始处理商品数据,来源:" + getSource());}// 具体方法,记录处理完成日志private void logCompletion(Product product) {System.out.println("商品数据处理完成,结果:" + product);}// 具体方法,处理验证失败的情况protected void handleValidationFailure(String rawData) {System.out.println("数据验证失败:" + rawData);}// 抽象方法,子类需要实现以返回数据来源protected abstract String getSource();
}

子类定制 - 适配不同供应商

接下来,我们为每个供应商创建具体的子类,实现抽象基类中的抽象方法。

供应商 A 的数据处理器

@Component
public class SupplierADataHandler extends AbstractProductDataHandler {@Overrideprotected boolean validateData(String rawData) {// 简单的 JSON 格式验证return rawData != null && rawData.startsWith("{") && rawData.endsWith("}");}@Overrideprotected Product parseData(String rawData) {// 解析 JSON 数据// 实际项目中,可以使用 Jackson 或 Gson 等库Product product = new Product();product.setName("SupplierA Product");product.setPrice(100.0);return product;}@Overrideprotected void processProduct(Product product) {// 对商品名称进行标准化处理product.setName(product.getName().toUpperCase());}@Overrideprotected String getSource() {return "Supplier A";}
}

供应商 B 的数据处理器

@Component
public class SupplierBDataHandler extends AbstractProductDataHandler {@Overrideprotected boolean validateData(String rawData) {// 简单的 XML 格式验证return rawData != null && rawData.startsWith("<") && rawData.endsWith(">");}@Overrideprotected Product parseData(String rawData) {// 解析 XML 数据// 实际项目中,可以使用 JAXB 或 DOM 解析器Product product = new Product();product.setName("SupplierB Product");product.setPrice(200.0);return product;}@Overrideprotected void processProduct(Product product) {// 对商品价格进行汇率转换product.setPrice(product.getPrice() * 0.85); // 假设汇率为 0.85}@Overrideprotected String getSource() {return "Supplier B";}
}

在业务代码中整合运用

最后,我们在业务代码中使用这些数据处理器。通过 Spring 的依赖注入机制,我们可以轻松地切换不同的处理器。

@Service
public class ProductDataProcessingService {@Autowiredprivate SupplierADataHandler supplierAHandler;@Autowiredprivate SupplierBDataHandler supplierBHandler;public void processDataFromSupplierA(String rawData) {supplierAHandler.handleProductData(rawData);}public void processDataFromSupplierB(String rawData) {supplierBHandler.handleProductData(rawData);}
}

8. 总结

模板方法模式通过定义算法的骨架并将某些步骤的具体实现延迟到子类中,提供了一种灵活且可扩展的设计方式。它在代码复用、扩展性和灵活性方面具有显著优势,适用于需要固定流程但允许部分步骤自定义的场景。通过合理使用模板方法模式,可以构建出清晰、可维护且易于扩展的代码架构。
在这里插入图片描述

相关文章:

设计模式 - 行为模式_Template Method Pattern模板方法模式在数据处理中的应用

文章目录 概述1. 核心思想2. 结构3. 示例代码4. 优点5. 缺点6. 适用场景7. 案例&#xff1a;模板方法模式在数据处理中的应用案例背景UML搭建抽象基类 - 数据处理的 “总指挥”子类定制 - 适配不同供应商供应商 A 的数据处理器供应商 B 的数据处理器 在业务代码中整合运用 8. 总…...

新春登蛇山:告别岁月,启航未来

大年初一&#xff0c;晨曦透过薄雾&#xff0c;温柔地洒在武汉的大街小巷。2025 年的蛇年春节&#xff0c;带着新春的喜气与希望悄然而至。我站在蛇山脚下&#xff0c;心中涌动着复杂的情感&#xff0c;因为今天&#xff0c;我不仅将与家人一起登山揽胜&#xff0c;更将在这一天…...

hive:基本数据类型,关于表和列语法

基本数据类型 Hive 的数据类型分为基本数据类型和复杂数据类型 加粗的是常用数据类型 BOOLEAN出现ture和false外的其他值会变成NULL值 没有number,decimal类似number 如果输入的数据不符合数据类型, 映射时会变成NULL, 但是数据本身并没有被修改 创建表 创建表的本质其实就是在…...

安装最小化的CentOS7后,执行yum命令报错Could not resolve host mirrorlist.centos.org; 未知的错误

文章目录 安装最小化的CentOS7后&#xff0c;执行yum命令报错"Could not resolve host: mirrorlist.centos.org; 未知的错误"错误解决方案&#xff1a; 安装最小化的CentOS7后&#xff0c;执行yum命令报错"Could not resolve host: mirrorlist.centos.org; 未知…...

图论——spfa判负环

负环 图 G G G中存在一个回路&#xff0c;该回路边权之和为负数&#xff0c;称之为负环。 spfa求负环 方法1:统计每个点入队次数, 如果某个点入队n次, 说明存在负环。 证明&#xff1a;一个点入队n次&#xff0c;即被更新了n次。一个点每次被更新时所对应最短路的边数一定是…...

软件工程概论试题三

一、单选 1.需求确认主要检査五个方面的内容&#xff0c;其中那一项是为了保证文档中的需求不互相冲突(即不应该有相互矛盾的约束或者对同一个系统功能有不同的描述)。 A.现实性 B. 可验证性 C.一致性 D.正确性 E.完整性 正答&#xff1a;C 2.下列开发方法中&#xff0c;( )不…...

21.3-启动流程、编码风格(了解) 第21章-FreeRTOS项目实战--基础知识之新建任务、启动流程、编码风格、系统配置 文件组成和编码风格(了解)

21.3-启动流程、编码风格(了解) 启动流程 第一种启动流程(我们就使用这个): 在main函数中将硬件初始化、RTOS系统初始化&#xff0c;同时创建所有任务&#xff0c;再启动RTOS调度器。 第二种启动流程&#xff1a; 在main函数中将硬件初始化、RTOS系统初始化&#xff0c;只…...

未来无线技术的发展方向

未来无线技术的发展趋势呈现出多样化、融合化的特点&#xff0c;涵盖速度、覆盖范围、应用领域、频段利用、安全性等多个方面。这些趋势将深刻改变人们的生活和社会的运行方式。 传输速度提升&#xff1a;Wi-Fi 技术迭代加快&#xff0c;如 Wi-Fi7 理论峰值速率达 46Gbps&#…...

Qt5离线安装包无法下载问题解决办法

想在电脑里装一个Qt&#xff0c;但是直接报错。果然还是有解决办法滴。 qt download from your ip is not allowed Qt5安装包下载办法 方法一&#xff1a;简单直接&#xff0c;直接科学一下&#xff0c;不过违法行为咱不做&#xff0c;遵纪守法好公民&#xff08;不过没办法阻…...

qt-C++笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphicsRectItem的区别

qt-C笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphicsRectItem的区别 code review! 参考笔记 1.qt-C笔记之重写QGraphicsItem的paint方法(自定义QGraphicsItem) 文章目录 qt-C笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphic…...

doris:导入时实现数据转换

Doris 在数据导入时提供了强大的数据转换能力&#xff0c;可以简化部分数据处理流程&#xff0c;减少对额外 ETL 工具的依赖。主要支持以下四种转换方式&#xff1a; 列映射&#xff1a;将源数据列映射到目标表的不同列。 列变换&#xff1a;使用函数和表达式对源数据进行实时…...

新版231普通阿里滑块 自动化和逆向实现 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向过程 补环境逆向 部分补环境 …...

如何构建树状的思维棱镜认知框架

在思维与知识管理中&#xff0c;“树状思维棱镜”通常指一种层级式、可多维度展开和不断深入&#xff08;下钻&#xff09;的认知框架。它不仅仅是普通的树状结构&#xff08;如传统思维导图&#xff09;&#xff0c;更强调“棱镜”所体现的多视角、多维度切换与综合分析的能力…...

openRv1126 AI算法部署实战之——ONNX模型部署实战

在RV1126开发板上部署ONNX算法&#xff0c;实时目标检测RTSP传输。视频演示地址 rv1126 yolov5 实时目标检测 rtsp传输_哔哩哔哩_bilibili 一、准备工作 1.从官网下载YOLOv5-v7.0工程&#xff08;YOLOv5的第7个版本&#xff09; 手动在线下载&#xff1a; Releases ultraly…...

Vue 组件开发:构建高效可复用的前端界面要素

1 引言 在现代 Web 开发中,构建高效且可复用的前端界面要素是提升开发效率和用户体验的关键。Vue.js 作为一种轻量级且功能强大的前端框架,提供了丰富的工具和机制,帮助开发者快速构建高质量的应用程序。通过合理设计和封装 Vue 组件,我们可以实现组件的高效复用,提高开发…...

Vue.js组件开发-实现全屏平滑移动、自适应图片全屏滑动切换

使用Vue实现全屏平滑移动、自适应图片全屏滑动切换的功能。使用Vue 3和Vue Router&#xff0c;并结合一些CSS样式来完成这个效果。 步骤 创建Vue项目&#xff1a;使用Vue CLI创建一个新的Vue项目。准备图片&#xff1a;将需要展示的图片放在项目的public目录下。创建组件&…...

水果实体店品牌数字化:RWA + 智能体落地方案

一、方案背景 随着数字化技术的迅猛发展&#xff0c;实体零售行业正面临前所未有的挑战与机遇。传统的零售模式难以满足消费者对个性化、便捷化、智能化的需求&#xff0c;尤其是在水果等生鲜商品领域&#xff0c;如何通过技术手段提升运营效率、增强顾客体验、拓宽盈利模式&a…...

DeepSeek模型:开启人工智能的新篇章

DeepSeek模型&#xff1a;开启人工智能的新篇章 在当今快速发展的技术浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;已经成为了推动社会进步和创新的核心力量之一。而DeepSeek模型&#xff0c;作为AI领域的一颗璀璨明珠&#xff0c;正以其强大的功能和灵活的用法&…...

Kubernetes 环境中的自动化运维实战指南

Kubernetes 作为容器编排领域的领导者,已经成为云原生应用的核心基础设施。然而,随着集群规模的扩大和应用的复杂化,手动运维 Kubernetes 集群变得愈发困难。自动化运维成为提升效率、保障系统稳定性的关键。本文将详细介绍如何在 Kubernetes 环境中实施自动化运维,涵盖工具…...

深入解析 C++17 中的 std::not_fn

文章目录 1. std::not_fn 的定义与目的2. 基本用法2.1 基本示例2.2 使用 Lambda 表达式2.3 与其他函数适配器的比较3. 在标准库中的应用3.1 结合标准库算法使用3.1.1 std::find_if 中的应用3.1.2 std::remove_if 中的应用3.1.3 其他标准库算法中的应用4. 高级技巧与最佳实践4.1…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...