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

设计模式-行为型模式-模板方法模式

一、什么是模板模式

        模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个算法骨架,允许子类在不改变算法整体结构的情况下重新定义算法的某些步骤。

        主要组成部分:

        1、模板方法(Template Method): 定义了算法的骨架结构,包含了一个算法的整体流程,并将某些步骤的实现推迟到子类中。通常作为一个抽象方法或者具有默认实现的方法。

        2、具体方法(Concrete Methods): 模板方法中的步骤可能有一些默认实现,在模板方法中直接实现的步骤。

        3、抽象方法(Abstract Methods): 在模板方法中留给子类实现的方法,用于子类实现具体步骤。

        工作原理:

        模板方法模式定义了一个固定算法的框架,其中一些步骤是固定的,而另一些可以由子类实现。抽象类中的模板方法规定了算法的结构和执行顺序,而具体的步骤则由子类实现。

二、场景模拟

        这里拿2023年海康威视秋招的一个问答题为例。题目是这么描述的:实现两个巡检任务,其中A巡检任务使用现场扫描二维码的方式巡检机房的服务器状态(正常/异常),B巡检任务使用远程视频方式巡检服务器正常运行率(百分比数字),两个巡检任务结束后都要提交巡检结果。使用模板方法设计模式解决。

        我们简单的将A和B任务的流程画出了,很简单,就是A使用二维码方式巡检,返回正常/异常的结果;B使用远程视频方式巡检,返回百分率。这里,我们发现,他们有着共同的流程,先巡检,再上报,可能有些方法的具体实现不一样,但是整体流程是确定的。

三、业务实现

        其中抽象类Inspect定义了巡检的流程,然后提供了默认的实现方法 。两个不同的巡检方法继承Inspect,可以根据需求自定义方法,也可以使用Inspect提供的默认实现方法。

3.1、使用模板类定义一个巡检框架

@Slf4j
public abstract class Inspect<T> {// 巡检名称private final String inspectName;public Inspect(String inspectName) {this.inspectName = inspectName;}public T startInspect(){initInspect();inspectFunction();return submitInspect();}/*** 初始化巡检方法*/protected void initInspect(){log.info("初始化巡查系统" + inspectName);}// 模拟不同的巡检方式protected abstract void inspectFunction();// 返回巡检信息protected abstract T submitInspect();
}

可以看到上方定义了三个流程,首先初始化,然后模拟不同的巡检方式,最后返回巡检信息。流程是固定的,只不过不同的巡检可能使用不同的方式,所以需要写单独的类去实现。

3.2、子类继承模板抽象类后自定义

例如巡检A,使用的是二维码的形式巡检,并返回(正常/异常)状态,我们用布尔值模拟。

@Slf4j
public class AInspect extends Inspect<Boolean> {public AInspect(String inspectName) {super(inspectName);}@Overrideprotected void inspectFunction() {log.info("使用二维码方式巡检……");}@Overrideprotected Boolean submitInspect() {return true;}
}

巡检B,使用的是远程视频监控的形式,并返回百分比比例,我们用double模拟;

@Slf4j
public class BInspect extends Inspect<Double> {public BInspect(String inspectName) {super(inspectName);}@Overrideprotected void inspectFunction() {log.info("使用远程视频监控方式巡检……");}@Overrideprotected Double submitInspect() {return 88.88d;}
}

3.3、测试

public static void main(String[] args) {Inspect<Boolean> inspectA = new AInspect("A任务");Boolean resultA = inspectA.startInspect();log.info("A巡视结果:{}", resultA);Inspect<Double> inspectB = new BInspect("B任务");Double resultB = inspectB.startInspect();log.info("B巡视结果:{}", resultB);}

可以看到运行结果,巡检系统A和B分别用不同的方式完成了巡检,且流程一致。

四、小结

        模板方法定义了一个算法的骨架,将一些步骤推迟到子类去实现。如果在我们的项目中,有一个业务流程是固定的,但是实现业务的方式是多变的,我们可以考虑模板方法,来优化我们的代码结构。

        可能有些人分不清楚模板方法和策略模式的区别,这里我区分一下。

        首先就定义和结构方面:模板方法用抽象类定义了一系列的流程,子类继承他的流程,但是可以修改流程某个点的实现方式或者是继承父类的默认实现方式;策略模式是定义一个接口,多个类去实现这个接口,允许客户端在运行时选择使用的策略。

        它们的目的也是不一样的:模板方式是确保各个步骤执行顺序,一定层面上减少重复代码;策略模式是让调用者自由的选择实现方式或行为,且多个实现方式之前可以替换。

        区分谁是谁并不怎么重要,因为在一念之间,他们有可能会相互替换,需要看自己的业务需求。而且很多时候,这两种设计模式可能配合使用,实现拓展和定制,这里我举例一种情况。就拿策略模式这个来说,我这里只写了计算某种材料的计算策略,但是在实际的业务中,我们可能需要统计这一个月或者一年的材料成本量,就简单来说,我们需要算出这一个月的使用量,然后这一年的使用量是这12个月加起来的使用量。这个流程就大致为:计算出某一条记录的成本;计算出一个月的成本;计算出一年的成本。我们就可以定义一个模板方法,算不同材料的年成本。这里我们就可以嵌套进去我们的策略模式,让两者搭配使用,完成业务需求。当然两者配合的场景可能有很多,这里我举得例子可能不是那么恰当,但是也差不多这个意思。

相关文章:

设计模式-行为型模式-模板方法模式

一、什么是模板模式 模板方法模式&#xff08;Template Method Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了一个算法骨架&#xff0c;允许子类在不改变算法整体结构的情况下重新定义算法的某些步骤。 主要组成部分&#xff1a; 1、模板方法&#xff08;Templ…...

露营管理系统预约小程序效果如何

旅游经济已经复苏&#xff0c;并且市场规模增速加快&#xff0c;近一年来远途/周边游客户增多&#xff0c;不少旅游景区在节假日常常面对客流爆满现象。同时露营作为近几年突然火热的项目&#xff0c;其需求也是日渐上升。 然而在高需求的同时&#xff0c;我们也看到露营经营痛…...

【产品安全平台】上海道宁与Cybellum将整个产品安全工作流程整合到一个专用平台中,保持构建的互联产品的网络安全和网络合规性

Cybellum将 整个产品安全工作流程 整合到一个专用平台中 使设备制造商能够 保持他们构建的互联产品的 网络安全和网络合规性 产品安全性对 每个人来说都不一样 每个行业的系统、工作流程和 法规都存在根本差异 因此&#xff0c;Cybellum量身定制了 Cybellum的平台和技…...

css 实现鼠标上移添加下划线

效果图 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-wi…...

C语言--给定一个数组,把第一项的值减去第二项的值,第二项的值减去第三项的值,第三项的值减去第四项的值,依次类推。放到一个新的数组中,并打印新的数组

一.题目描述&#xff1a; 给定一个数组&#xff0c;把第一项的值减去第二项的值&#xff0c;第二项的值减去第三项的值&#xff0c;第三项的值减去第四项的值&#xff0c;依次类推。放到一个新的数组中&#xff0c;并打印新的数组。 比如&#xff1a;输入一个数组是5&#xff…...

Vue+Swiper实现轮播图效果

效果展示 实现了自带切换按钮在图片外部实现了自定义的切换按钮 背景 在项目中使用到了轮播图&#xff0c;实现点击上一张下一张时实现循环显示&#xff0c;同时预览两个图片&#xff0c;并加以文字对图片的说明。 设计 使用 Swiper 插件&#xff0c;可以实现当前这个需求。…...

竞赛选题 行人重识别(person reid) - 机器视觉 深度学习 opencv python

文章目录 0 前言1 技术背景2 技术介绍3 重识别技术实现3.1 数据集3.2 Person REID3.2.1 算法原理3.2.2 算法流程图 4 实现效果5 部分代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习行人重识别(person reid)系统 该项目…...

解决vue中引入天地图显示不全问题,设置setTimeout即可解决!

index.html中引入天地图api <script type"text/javascript" src"https://api.tianditu.gov.cn/api?v4.0&tk你的key"></script>map.vue中初始化天地图 //初始化天地图 initTMap() {const T window.T;// 3.初始化地图对象this.tMap new…...

【OpenCV实现图像:使用OpenCV进行物体轮廓排序】

文章目录 概要读取图像获取轮廓轮廓排序小结 概要 在图像处理中&#xff0c;经常需要进行与物体轮廓相关的操作&#xff0c;比如计算目标轮廓的周长、面积等。为了获取目标轮廓的信息&#xff0c;通常使用OpenCV的findContours函数。然而&#xff0c;一旦获得轮廓信息后&#…...

【8】Spring Boot 3 集成组件:安全组件 spring security【官网概念篇】

目录 【8】Spring Boot 3 集成组件&#xff1a;安全组件 spring securitySpring Security 简介先决条件引入依赖身份验证密码存储密码存储历史DelegatingPasswordEncoder密码存储格式密码加解密类自定义密码存储 体系结构 ArchitectureServlet 过滤器DelegatingFilterProxyFilt…...

UDP中connect的作用

udpclientNoConnect.c里边的内容如下&#xff1a; #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/socket.h> #include <errno.h> #include <syslog.h…...

Go使用开源库go-excelize操作Excel文件

以下是一个示例代码&#xff0c;读取一个 Excel 文件并打印其中的所有单元格值&#xff1a; package mainimport ("fmt""github.com/30x/go-excelize" )func main() {// 打开 Excel 文件f, err : excelize.OpenFile("yourfile.xlsx")if err ! n…...

软件测试个人求职简历该怎么写,模板在这里

1、个人资料 姓名&#xff1a;xxx性别&#xff1a;x 手机号码&#xff1a;138888888xx邮箱&#xff1a;xxx 学历&#xff1a;本科专业&#xff1a;电子商务 英语&#xff1a;四级当前工作&#xff1a;测试工程师 从业时间&#xff1a;4年期望薪资&#xff1a;面议 求职意向软件…...

opencv-Hough 圆环变换

Hough 圆环变换&#xff08;Hough Circle Transform&#xff09;是一种用于在图像中检测圆环的技术。与 Hough 直线变换类似&#xff0c;它通过在参数空间中表示图像中的圆环&#xff0c;将圆环检测问题转换为参数空间的累加问题。OpenCV 提供了 cv2.HoughCircles() 函数来执行…...

福州大学《嵌入式系统综合设计》实验五:图像裁剪及尺寸变换

一、实验目的 在深度学习中&#xff0c;往往需要从一张大图中裁剪出一张张小图&#xff0c;以便适应网络输入图像的尺寸&#xff0c;这可以通过bmcv_image_crop函数实现。 实践中&#xff0c;经常需要对输入图像的尺寸进行调整&#xff0c;以适用于网络输入图片尺寸&#xff0…...

LLM之Prompt(二):清华提出Prompt 对齐优化技术BPO

论文题目&#xff1a;《Black-Box Prompt Optimization: Aligning Large Language Models without Model Training》 论文链接&#xff1a;https://arxiv.org/abs/2311.04155 github地址&#xff1a;https://github.com/thu-coai/BPO BPO背景介绍 最近&#xff0c;大型语言模…...

chatglm3部署使用

chatglm3部署使用 1.部署2.使用3.接入微信4.vue前端 1.部署 1.首先去github下载chatglm3代码。Huggingface下载模型一直失败&#xff0c;所以用阿里的魔塔社区下载。 git clone https://github.com/THUDM/ChatGLM3.git git clone https://www.modelscope.cn/ZhipuAI/chatglm3…...

Android扫码ZXing

1. 获取权限 请注意动态申请及重写申请结果返回方法。 <uses-permission android:name"android.permission.CAMERA"/> 2. 添加依赖 //Gradle Scripts -> build.gradle(Module:app) implementation com.google.zxing:core:3.4.1 implementation com.jour…...

求解Beamforming-SOCP(CVX求解)

时间&#xff1a;2023年11月23日14:00:16&#xff1a; 直接上代码&#xff08;辛苦两天才改出来的&#xff09; clear all; K 4; %user number N4; %base station number var1e-9; H []; %initialize H matrix for i1:Kh 1/sqrt(2*K)*mvnrnd(zeros(N,1),eye(N),1)1i/sqrt(2*…...

解决Vue项目的runtime-only转为runtime-compiler

我们在vue.config.js中添加上 runtimeCompiler: true,然后再将main.js入口文件中的Vue实例改为以下即可 //修改前 new Vue({router,store,render: (h) > h(App) }).$mount(#app) //修改后 new Vue({el:#app,router,store, components:{App}, template:<App/>})...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

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

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

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

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

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

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...

CSS3相关知识点

CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...

未授权访问事件频发,我们应当如何应对?

在当下&#xff0c;数据已成为企业和组织的核心资产&#xff0c;是推动业务发展、决策制定以及创新的关键驱动力。然而&#xff0c;未授权访问这一隐匿的安全威胁&#xff0c;正如同高悬的达摩克利斯之剑&#xff0c;时刻威胁着数据的安全&#xff0c;一旦触发&#xff0c;便可…...