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

一、什么是模板模式

        模板方法模式(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个月加起来的使用量。这个流程就大致为:计算出某一条记录的成本;计算出一个月的成本;计算出一年的成本。我们就可以定义一个模板方法,算不同材料的年成本。这里我们就可以嵌套进去我们的策略模式,让两者搭配使用,完成业务需求。当然两者配合的场景可能有很多,这里我举得例子可能不是那么恰当,但是也差不多这个意思。

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

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

相关文章

JS解决跨域问题

在JavaScript中&#xff0c;解决跨域问题主要可以通过以下几种方法&#xff1a; JSONP (JSON with Padding)&#xff1a; JSONP 是通过在 DOM 中插入 <script> 标签&#xff0c;利用 script 标签的 src 属性不受同源策略限制的特性&#xff0c;实现跨域数据请求。示例&am…

论文笔记:Localizing Cell Towers fromCrowdsourced Measurements

2015 1 Intro 1.1 motivation opensignal.com 、cellmapper.net 和 opencellid.org 都是提供天线&#xff08;antenna&#xff09;位置的网站 他们提供的天线位置相当准确&#xff0c;但至少在大多数情况下不完全正确这个目标难以实现的原因是蜂窝网络供应商没有义务提供有…

.NET 使用配置文件

我简单测试了一下json格式配置文件&#xff0c;在这里记录一下&#xff0c;方便以后查看。 需要引用的库&#xff1a; Microsoft.Extensions.Hosting 创建json格式文件&#xff1a;appsettings.json 在工程文件中包含json文件&#xff1a; <ItemGroup><Content In…

面试题:数据库日期类型字段,需要兼容不同数据库,应该如何选择?

当设计一个产品&#xff0c;其中很多地方要把日期类型保存到数据库中&#xff0c;如果产品有兼容不同数据库产品的需求&#xff0c;那么&#xff0c;应当怎样设计呢&#xff1f; 当然&#xff0c;首先想到的是&#xff0c;使用数据库的 Date 或 DateTime 类型&#xff0c;可是…

wincc定时器功能介绍

1定时器功能介绍 WinCC中定时器的使用可以使WinCC按照指定的周期或者时间点去执行任务&#xff0c;比如周期执行变量归档、在指定的时间点执行全局脚本或条件满足时打印报表。WinCC已经提供了一些简单的定时器&#xff0c;可以满足大部分定时功能。但是在有些情况下&#xff0c…

Python 基础语法 Hello, World!

Python 基础语法 import concurrent.futures import threading import timedef switch_case(argument):switch {1: "这是第一种情况",2: "这是第二种情况",3: "这是第三种情况"}return switch.get(argument, "这是默认情况")def my_…

【计算机网络】多路复用的三种方案

文章目录 1. selectselect函数select的工作特性select的缺点 2. pollpoll函数poll与select的对比 3. epollepoll的三个接口epoll的工作原理epoll的优点LT和ET模式epoll的应用场景 &#x1f50e;Linux提供三种不同的多路转接&#xff08;又称多路复用&#xff09;的方案&#xf…

6、信息打点——Web架构篇语言中间件数据库系统源码获取

1、信息搜集搜集哪些东西&#xff1f; 架构信息收集&#xff0c;主要包括&#xff1a;操作系统、开发语言、中间件容器、数据库类型、第三方软件等&#xff1b; web源码信息收集&#xff0c;CMS开源&#xff1f;闭源&#xff1f;售卖&#xff1f;自主研发&#xff1f; 进行web…

【python FastAPI】fastapi中如何限制输入参数,如何让docs更好看,如何自定义错误码json返回

原则&#xff1a; 输入输出都基于BaseModel依靠JSONResponse制定返回错误的json信息依靠装饰器中app.post制定responses字典从而让docs文档更丰富 import uvicorn from pydantic import BaseModel, Field from fastapi import FastAPI, HTTPException from fastapi.middleware…

Python之pyc文件的生成与反编译

目录 1、什么是pyc文件 2、手动生成pyc文件 3、pyc文件的执行 4、pyc文件的反编译 1、什么是pyc文件 pyc文件&#xff08;PyCodeObject&#xff09;是Python编译后的结果。当python程序运行时&#xff0c;编译的结果是保存于PyCodeObject&#xff0c;程序运行结束后&#x…

(动手学习深度学习)第13章 实战kaggle竞赛:狗的品种识别

文章目录 1. 导入相关库2. 加载数据集3. 整理数据集4. 图像增广5. 读取数据6. 微调预训练模型7. 定义损失函数和评价损失函数9. 训练模型 1. 导入相关库 import os import torch import torchvision from torch import nn from d2l import torch as d2l2. 加载数据集 - 该数据…

编程中的各种常见的文件编码有哪些?

在计算机编程中&#xff0c;常见的文件编码有很多种。下面是一些常见的文件编码&#xff1a; UTF-8&#xff08;Unicode Transformation Format - 8-bit&#xff09;&#xff1a; 它是一种变长字符编码&#xff0c;能够表示世界上几乎所有的字符&#xff0c;是最常用的 Unicode…

java抽象类和static

抽象类 并不是所有的类都是用来描绘对象的, 如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类 使用abstract 修饰类抽象类不能被实例化。在抽象类当中&#xff0c;可以有抽象方法&#xff0c;或者 非抽象方法!什么是抽象方法&#xff0c;一个方…

基于野马算法优化概率神经网络PNN的分类预测 - 附代码

基于野马算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于野马算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于野马优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…

【FPGA】Verilog:计数器 | 异步计数器 | 同步计数器 | 2位二进制计数器的实现 | 4位十进制计数器的实现

目录 Ⅰ. 实践说明 0x00 计数器(Counter) 0x01 异步计数器(Asynchronous Counter)

深度学习中的图像融合:图像融合论文阅读与实战

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 abs 介绍图像融合概念&#xff0c;回顾sota模型&#xff0c;其中包括数字摄像图像融合&#xff0c;多模态图像融合&#xff0c; 接着评估一些代表方法 介绍一些常见应用&#xff0c;比如RGBT目标跟踪&#xff0c;…

鸿蒙4.0开发笔记之DevEco Studio启动时不直接打开原项目(二)

1、想要在DevEco Studio启动时不直接打开关闭前的那个项目&#xff0c;可以在设置中进行。 有两个位置可以进入“设置”&#xff0c;一个是左上角的File>Settings&#xff0c;二是右上方的设置图标。 2、进入Settings界面以后&#xff0c;选择Appearance&Behavior下面…

Java Stream中的API你都用过了吗?

公众号「架构成长指南」&#xff0c;专注于生产实践、云原生、分布式系统、大数据技术分享。 在本教程中&#xff0c;您将通过大量示例来学习 Java 8 Stream API。 Java 在 Java 8 中提供了一个新的附加包&#xff0c;称为 java.util.stream。该包由类、接口和枚举组成&#x…

AIGC创作系统ChatGPT网站系统源码,支持最新GPT-4-Turbo模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…