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

设计模式之模版方法实践

模版方法实践案例

实践之前还是先了解一下模版方法的定义

定义

模板方法模式是一种行为设计模式,它定义了一个骨架,并允许子类在不改变结构的情况下重写的特定步骤。模板方法模式通过在父类中定义一个模板方法,其中包含了主要步骤,而将一些步骤的实现留给子类。这样,子类可以在不改变算法整体结构的情况下,根据需要重新实现某些步骤。

在什么情况下要使用模版方法呢?设计模式不能生搬硬套,而是在一些适合的场景下进行使用,否则会适得其反,可以看看这篇文章http://www.ayqy.net/blog/设计模式总结(《head-first设计模式》学习总结)

进入正题

以下是我项目应用模版方法的代码片段

/*** @Author: HWQ* @Version: 1.0* @Description: 基本api请求*/
public abstract class BaseRequest<O, T extends ResultResponse> {private Map<String, Object> requestParams = new HashMap<>();/*** get方法** @return {@link}*/public abstract String getMethod();/*** 获取路径** @return {@link String}*/public abstract String getPath();/*** 获取响应类** @return {@link Class}<{@link T}>*/public abstract Class<T> getResponseClass();@JsonAnyGetterpublic Map<String, Object> getRequestParams() {return requestParams;}public void setRequestParams(O params) {// 将JSON对象转为Mapthis.requestParams = new Gson().fromJson(JSONUtil.toJsonStr(params), new TypeToken<Map<String, Object>>() {}.getType());}
}

BaseRequest定义了骨架,具体的步骤包括获取请求方法(getMethod)、获取路径(getPath)、获取响应类(getResponseClass)等。

/*** @author HWQ* @date 2024/2/28 11:54* @description*/@Accessors(chain = true)
public class ChatAIRequest extends BaseRequest<ChatAIParams, ResultResponse> {@Overridepublic String getPath() {return "/chatAi";}/*** 获取响应类** @return {@link Class}<{@link NameResponse}>*/@Overridepublic Class<ResultResponse> getResponseClass() {return ResultResponse.class;}@Overridepublic String getMethod() {return RequestMethodEnum.GET.getValue();}
}

ChatAIRequest继承了BaseRequest这个抽象类,实现了获取请求方法(getMethod)、获取路径(getPath)、获取响应类(getResponseClass)

分析一下

好处在哪?

  1. 提高代码一致性

如果我的系统中仅有ChatAIRequest这个类,那我大可不必采用模版方法

问题是我的项目中有大量的Request类,并且这个Request的骨架是相同的,所以这些Request类只需要继承BaseRequest这个抽象类,实现各自的获取请求方法(getMethod)、获取路径(getPath)、获取响应类(getResponseClass)即可

在这里插入图片描述

  1. 减少重复代码: 具体的请求类(例如 chatAiRequest)无需重复实现算法的整体结构,只需专注于实现特定的步骤,如获取请求方法、路径等。这降低了代码的冗余,符合"Don’t Repeat Yourself"(DRY)原则

  2. 提高代码的可维护性: 算法的整体结构集中在 BaseRequest 类中,使得代码更易理解和维护。如果有新的请求类需要添加,只需创建新的具体子类,并实现特定的步骤,而不需要修改已有的代码

相关文章:

设计模式之模版方法实践

模版方法实践案例 实践之前还是先了解一下模版方法的定义 定义 模板方法模式是一种行为设计模式&#xff0c;它定义了一个骨架&#xff0c;并允许子类在不改变结构的情况下重写的特定步骤。模板方法模式通过在父类中定义一个模板方法&#xff0c;其中包含了主要步骤&#xf…...

sql中COALESCE函数详解

在SQL中&#xff0c;COALESCE函数是一个非常有用的函数&#xff0c;用于从其参数列表中返回第一个非NULL值。如果所有给定的参数都是NULL&#xff0c;那么COALESCE函数将返回NULL。这个函数可以接受多个参数&#xff0c;使其在处理可能出现的NULL值时非常灵活和强大。 语法 C…...

rust-analyzer报错“Failed to spawn one or more proc-macro servers,....“怎么解决?

最近,在使用vscode测试rust代码时,遇到了一些问题。在经过反复折腾后,最终解决了问题,在此写下作为记录,以便于以后参考。 我遇到的报错内容是: Failed to spawn one or more proc-macro servers. cannot find proc-macro-srv, the workspace E:\100rust\temp is missin…...

Communications--9--一文读懂双机热备冗余原理

1、热备冗余管理 2、主备系状态判断 3、如何从冷备做到热备&#xff1f; 参见&#xff1a; 用软件实现热备冗余信号系统的安全切换...

可调恒定电流稳压器NSI50150ADT4G车规级LED驱动器 提供专业的汽车级照明解决方案

NSI50150ADT4G产品概述&#xff1a; NSI50150ADT4G可调恒定电流稳压器 (CCR) &#xff0c;是一款简单、经济和耐用的器件&#xff0c;适用于为 LED 中的调节电流提供成本高效的方案&#xff08;与恒定电流二极管 CCD 类似&#xff09;。该 (CCR) 基于自偏置晶体管 (SBT) 技术&…...

Unity中使用代码动态修改URP管线下的标准材质是否透明

//修改为透明 material.SetFloat("_Surface",1.0f); material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.Set…...

关于制作Python游戏全过程(汇总1)

目录 前言: 1.plane_sprites模块: 1.1导入模块: 1.1.1pygame&#xff1a;一个用于创建游戏的Python库。 1.1.2random&#xff1a;Python标准库中的一个模块&#xff0c;用于生成随机数。 1.2定义事件代号: 1.2.1ENEMY_EVENT&#xff1a;自定义的敌机出场事件代号&#xf…...

独立站营销新纪元:AI与大数据塑造个性化体验的未来

随着全球互联网的深入发展和数字化转型的不断推进&#xff0c;作为品牌建设和市场营销的重要载体&#xff0c;独立站将迎来新的发展机遇。新技术的涌现&#xff0c;特别是人工智能和大数据等技术的广泛应用&#xff0c;为独立站带来了前所未有的机遇与挑战。本文Nox聚星将和大家…...

C语言项目实战——贪吃蛇

C语言实现贪吃蛇 前言一、 游戏背景二、游戏效果演示三、课程目标四、项目定位五、技术要点六、Win32 API介绍6.1 Win32 API6.2 控制台程序6.3 控制台屏幕上的坐标COORD6.4 GetStdHandle6.5 GetConsoleCursorInfo6.5.1 CONSOLE_CURSOR_INFO 6.6 SetConsoleCursorInfo6.7 SetCon…...

ArmSoM规划开发基于RK3576的开发套件

ArmSoM正计划推出一款新的产品&#xff0c;这款产品将采用强大的RK3576芯片。 本文将为您介绍我们的新产品搭载的RK3576性能参数&#xff0c;以及它如何为您提供卓越的性能和功能。 RK3576处理器 RK3576处理器是一款强大的处理器&#xff0c;具备出色的性能和多样化的功能&a…...

视频剪辑如何提取伴奏?短视频剪辑有妙方

在多媒体处理中&#xff0c;音频的编辑和处理是不可或缺的一部分。很多时候&#xff0c;我们可能想要从一段视频或音频中提取伴奏&#xff0c;或者实现人声的分离&#xff0c;以便于进一步制作或混音。以下&#xff0c;将为您介绍一种简单而有效的方法来实现这一目标。 一、提取…...

【Web】浅浅地聊SnakeYaml反序列化两条常见利用链

目录 关于Yaml 关于SnakeYaml SnakeYaml反序列化利用 JdbcRowSetImpl链 ScriptEngineManager链 复现 基本原理 继续深入 关于Yaml 学过SpringBoot开发的师傅都知道&#xff0c;YAML和 Properties 文件都是常见的配置文件格式&#xff0c;用于存储键值对数据。 这里举…...

详解openGauss客户端工具gsql的高级用法

前言&#xff1a; gsql是openGauss提供在命令行下运行的数据库连接工具&#xff0c;可以通过此工具连接服务器并对其进行操作和维护&#xff0c;除了具备操作数据库的基本功能&#xff0c;gsql还提供了若干高级特性&#xff0c;便于用户使用。 gsql的基本功能 连接数据库&…...

开源工业软件:SCADA系统开源

PyScada是一个开源的scada系统 源代码地址 http://www.gitpp.com/huangtomy/pyscada-cn SCADA系统是Supervisory Control And Data Acquisition的缩写&#xff0c;即数据采集与监视控制系统。它是以计算机为基础的DCS与电力自动化监控系统&#xff0c;应用领域非常广&#x…...

关于AI彩票预测算法的设想

本文以双色球选择红色6个号码为例 我们先把问题简化&#xff0c;双色球红色号码一共有33个球。摇奖时&#xff0c;每次随机摇出来一个号码&#xff0c;连续6次&#xff0c;就随机出来了6个红色球号码。 而这6个号码就是一注彩票里的前6个红色球号码。这里不讨论一注彩票里后端…...

设计模式之策略模式实践

设计模式之策略模式实践 先了解一下策略模式的定义是什么&#xff1f;解决什么问题 策略模式是一种行为设计模式&#xff0c;它定义了一系列算法&#xff0c;将每个算法封装成一个类&#xff0c;并使它们可以互相替换。策略模式允许客户端在运行时从可互换的算法中选择一个&a…...

讨论:解决哈希冲突的几种方法

1. 什么是哈希 哈希是通过对数据进行再压缩&#xff0c;提高效率的一种解决方法。 2. 什么时候会产生哈希冲突 通过哈希函数产生的哈希值是有限的&#xff0c;当数据量比较大时经过哈希函数处理后仍然有不同的数据对应相同的值。这时候就产生了哈希冲突。 3. 常见的哈希函数 1&…...

遥感分析时什么情况下需要做大气校正?

经常会遇到这样的问题&#xff1a;什么情况需要做大气校正产生&#xff1f;这个问题取决于传感器和应用目标&#xff0c;总的来说&#xff0c;如果要做光谱分析&#xff0c;那么大气校正是必须要做的。本文对于在什么情况下选择什么样的大气校正方法&#xff0c;给出了一些依据…...

设计模式学习笔记 - 设计原则 - 7.DRY 原则及提高代码复用性

前言 DRY 原则&#xff0c;英文描述为&#xff1a; Don’t Repeat Yourself。中文直译&#xff1a;不要重复自己。将它应用在编程中&#xff0c;可理解为&#xff1a;不要写重读的代码。 可能你认为&#xff0c;这个原则很简单。只要两段代码长得一样&#xff0c;那就是违反 …...

方法的调用

自定函数(方法) 函数(方法): 给定一个具有独立功能的代码片段进行"命名",并通过该该类名调用"方法" main主函数 在当前类中,可以直接调用方法(因为方法使用了static关键字) package study;import java.time.LocalDate; import java.time.format.Date…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...