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

Go和Java实现模板模式

Go和Java实现模板模式

下面通过一个游戏的例子来说明模板模式的使用。

1、模板模式

在模板模式中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将

以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

  • 意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的

    结构即可重定义该算法的某些特定步骤。

  • 主要解决:一些方法通用,却在每一个子类都重新写了这一方法。

  • 何时使用:有一些通用的方法。

  • 如何解决:将这些通用算法抽象出来。

  • 关键代码:在抽象类实现,其他步骤在子类实现。

  • 应用实例:1、在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异。

    2、西游记里面菩萨定好的 81 难,这就是一个顶层的逻辑骨架。 3、spring 中对 Hibernate 的支持,将一些

    已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好

    的代码,直接丢一个实体就可以保存。

  • 优点:1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现。

  • 缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。

  • 使用场景:1、有多个子类共有的方法,且逻辑相同。 2、重要的、复杂的方法,可以考虑作为模板方法。

  • 注意事项:为防止恶意操作,一般模板方法都加上 final 关键词。

  • 适用性:

    一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。

    各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复,首先识别现有代码中的不同之

    处,并且将不同之处分离为新的操作。最后用一个调用这些新的操作的模板方法来替换这些不同的代码。

    控制子类扩展。

2、Go实现模板模式

package templatemethod// ========== 创建一个抽象类,它的模板方法被设置为 final ==========
// ========== Game ==========
type Game interface {Initialize()StartPlay()EndPlay()Play()
}
package templatemethod// ========== BaseGame ==========
type BaseGame struct {Game
}func (b *BaseGame) Initialize() {
}func (b *BaseGame) StartPlay() {
}func (b *BaseGame) EndPlay() {
}func (b *BaseGame) Play() {b.Game.Initialize()b.Game.StartPlay()b.Game.EndPlay()
}
package templatemethodimport "fmt"// ========== Cricket ==========
type Cricket struct {BaseGame
}func (c *Cricket) Initialize() {fmt.Println("Cricket Game Initialized! Start playing.")
}func (c *Cricket) StartPlay() {fmt.Println("Cricket Game Started. Enjoy the game!")
}func (c *Cricket) EndPlay() {fmt.Println("Cricket Game Finished!")
}func (c *Cricket) Play() {c.BaseGame.Play()
}
package templatemethodimport "fmt"// ========== Football ==========
type Football struct {BaseGame
}func (f *Football) Initialize() {fmt.Println("Football Game Initialized! Start playing.")
}func (f *Football) StartPlay() {fmt.Println("Football Game Started. Enjoy the game!")
}func (f *Football) EndPlay() {fmt.Println("Football Game Finished!")
}func (f *Football) Play() {f.BaseGame.Play()
}
package mainimport ("fmt". "proj/templatemethod"
)func main() {var baseGame BaseGamecricket := Cricket{}baseGame = BaseGame{Game: &cricket}cricket.BaseGame = baseGamecricket.Play()fmt.Println("")football := Football{}baseGame = BaseGame{Game: &football}football.BaseGame = baseGamefootball.Play()
}
# 程序输出
Cricket Game Initialized! Start playing.
Cricket Game Started. Enjoy the game!
Cricket Game Finished!Football Game Initialized! Start playing.
Football Game Started. Enjoy the game!
Football Game Finished!

3、Java实现模板模式

package com.templatemethod;// ========== 创建一个抽象类,它的模板方法被设置为 final ==========
// ========== Game ==========
public abstract class Game {abstract void initialize();abstract void startPlay();abstract void endPlay();// 模板public final void play() {// 初始化游戏initialize();// 开始游戏startPlay();// 结束游戏endPlay();}
}
package com.templatemethod;// ========== Cricket ==========
public class Cricket extends Game {@Overridevoid endPlay() {System.out.println("Cricket Game Finished!");}@Overridevoid initialize() {System.out.println("Cricket Game Initialized! Start playing.");}@Overridevoid startPlay() {System.out.println("Cricket Game Started. Enjoy the game!");}
}
package com.templatemethod;// ========== Football ==========
public class Football extends Game {@Overridevoid endPlay() {System.out.println("Football Game Finished!");}@Overridevoid initialize() {System.out.println("Football Game Initialized! Start playing.");}@Overridevoid startPlay() {System.out.println("Football Game Started. Enjoy the game!");}
}
package com.templatemethod;public class Test {public static void main(String[] args) {Game game = new Cricket();game.play();System.out.println();game = new Football();game.play();}
}
# 程序输出
Cricket Game Initialized! Start playing.
Cricket Game Started. Enjoy the game!
Cricket Game Finished!Football Game Initialized! Start playing.
Football Game Started. Enjoy the game!
Football Game Finished!

相关文章:

Go和Java实现模板模式

Go和Java实现模板模式 下面通过一个游戏的例子来说明模板模式的使用。 1、模板模式 在模板模式中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将 以抽象类中定义的方式进行。这种类型的设计模式属于行为型…...

angular:quill align的坑

上一行设置了align为center,换行后下一个会继承上一行的格式,我想使用Quill.formatLine(newLineIndex, 0, ‘align’, left)来左对齐,发现始终不能生效。 参看quill.js源码,发现align没有left的配置 var config {scope: _parch…...

设计模式篇---抽象工厂(包含优化)

文章目录 概念结构实例优化 概念 抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。 工厂方法是有一个类型的产品,也就是只有一个产品的抽象类或接口,而抽象工厂相对于工厂方法来说,是有…...

Azure创建可用性集

什么是可用性集 在Azure中,可用性集(Availability Set)是一种用于提高虚拟机(VM)可用性和可靠性的功能。它通过将虚拟机分布在不同的物理硬件和故障域中来提供高可用性。每个故障域都是一个独立的电力和网络故障区域&…...

SpringBoot中优雅的实现隐私数据脱敏(提供Gitee源码)

前言:在实际项目开发中,可能会对一些用户的隐私信息进行脱敏操作,传统的方式很多都是用replace方法进行手动替换,这样会由很多冗余的代码并且后续也不好维护,本期就讲解一下如何在SpringBoot中优雅的通过序列化的方式去…...

Elasticsearch集群shard过多后导致的性能问题分析

1.问题现象 上午上班以后发现ES日志集群状态不正确,集群频繁地重新发起选主操作。对外不能正常提供数据查询服务,相关日志数据入库也产生较大延时 2.问题原因 相关日志 查看ES集群日志如下: 00:00:51开始集群各个节点与当时的master节点…...

Unity框架学习--5 事件中心管理器

作用:访问其它脚本时,不直接访问,而是通过发送一条“命令”,让监听了这条“命令”的脚本自动执行对应的逻辑。 原理: 1、让脚本向事件中心添加事件,监听对应的“命令”。 2、发送“命令”,事件…...

(二)结构型模式:3、过滤器模式(Filter、Criteria Pattern)(C++示例)

目录 1、过滤器模式(Filter、Criteria Pattern)含义 2、过滤器模式应用场景 3、过滤器模式主要几个关键角色 4、C实现过滤器模式的示例 1、过滤器模式(Filter、Criteria Pattern)含义 (1)过滤器模式是…...

谷歌在Chrome浏览器中推进抗量子加密技术

近日,Chromium博客上发表的一篇博文称,为了加强网络安全,应对迫在眉睫的量子计算机威胁,谷歌各个团队密切合作,为网络向抗量子密码学的过渡做好准备。 谷歌的Chrome团队在博客中写道,该项目涉及修订技术标准…...

Kotlin的数组

在 Kotlin 中,数组是一种固定大小的有序集合,可以存储相同类型的元素。Kotlin 提供了两种类型的数组:原生数组和数组类。以下是 Kotlin 中数组的详细使用方法: 1.创建数组 Kotlin 支持使用 arrayOf() 函数来创建数组:…...

centos 安装docker

1.更新你的系统: sudo yum update -y2.安装必需的软件包: Docker 需要 yum-utils, device-mapper-persistent-data 和 lvm2 软件包来运行。安装它们: sudo yum install -y yum-utils device-mapper-persistent-data lvm23.设置 Docker 的仓库: 使用以下命令添加 D…...

Oracle-如何判断字符串包含中文字符串(汉字),删除中文内容及保留中文内容

今天遇见一个问题需要将字段中包含中文字符串的筛选出来 --建表 CREATE TABLE HADOOP1.AAA ( ID VARCHAR2(255) ); --添加字段INSERT INTO HADOOP1.AAA(ID)VALUES(理解);....--查询表内容SELECT * FROM HADOOP1.AAA;在网上查找了一下有以下三种方式: 第一种&#…...

File 类的用法, InputStream和Reader, OutputStream和Writer 的用法

前言 普通的文件长这样: 其实目录也是一种特殊文件: 一、文件前缀知识 (一)绝对路径和相对路径 以盘符开头的的路径,叫做绝对路径,如:D:\360Downloads\cat.jpg 以.或..开头的路径&#xff0c…...

AtCoder Beginner Contest 315 Task:A/B/C/E

A - tcdr 处理字符串简单题&#xff0c;题目要求去除字符串中的a,e,i,o,u即可 #include<iostream> using namespace std; int main() {string s;cin>>s;for(int i0;i<s.length();i){if(s[i]a||s[i]e||s[i]i||s[i]o||s[i]u)continue;cout<<s[i];} }B - T…...

【项目实践】基于LSTM的一维数据扩展与预测

基于LSTM的一维数据拟合扩展 一、引(fei)言(hua) 我在做Sri Lanka生态系统服务价值计算时&#xff0c;中间遇到了一点小问题。从世界粮农组织(FAO)上获得Sri Lanka主要农作物产量和价格数据时&#xff0c;其中的主要作物Sorghum仅有2001-2006年的数据&#xff0c;而Millet只有…...

webshell实践,在nginx上实现负载均衡

1、配置多台虚拟机&#xff0c;用作服务器 在不同的虚拟机上安装httpd服务 我采用了三台虚拟机进行服务器设置&#xff1a;192.168.240.11、192.168.240.12、192.168.240.13 [rootnode0-8 /]# yum install httpd -y #使用yum安装httpd服务#开启httpd服务 [rootnode0-8 /]# …...

LVS+Keepalived集群

keepalived Keepalived及其工作原理 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案&#xff0c;可以解决静态路由出现的单点故障问题 在一个LVS服务集群中通常有主服务器&#xff08;MASTER&#xff09;和备份服务器&#xff08;BACKUP&#xff09;两种角色的服务…...

Java的网络编程

网络编程 两台设备之间通过网络实现数据传输&#xff0c;将数据通过网络从一台设备传输到另一台设备 网络 两台或多台设备通过一定物理设备连接起来构成了网络 网络又分为: 局域网:覆盖范围最小&#xff0c;仅仅覆盖一个教室或一个机房城域网:覆盖范围较大&#xff0c;可以…...

kafka配置远程连接

要想实现在本地连接服务器的kafka&#xff0c;则必须在远程kafka配置远程连接 默认的 kafka 配置是无法远程访问的&#xff0c;解决该问题有几个方案。 方案1 advertised.listenersPLAINTEXT://IP:9092 注意必须是 ip&#xff0c;不能是 hostname 方案2 advertised.listene…...

css实现渐变色border

方式1 div {border: 4px solid;border-image: linear-gradient(to right, #8f41e9, #578aef) 1; }/* 或者 */ div {border: 4px solid;border-image-source: linear-gradient(to right, #8f41e9, #578aef);border-image-slice: 1; }作者&#xff1a;MudOnTire 链接&#xff1a…...

管理 IBM Spectrum LSF

管理 IBM Spectrum LSF 了解如何管理 IBM Spectrum LSF 集群&#xff0c;控制守护程序&#xff0c;更改集群配置以及使用主机和队列。 管理 LSF 作业和作业调度策略。 查看作业信息和控制作业。 了解如何配置资源并将其分配给 LSF 作业。 了解如何在 LSF 集群中提交&#xff0…...

117页数字化转型与产业互联网发展趋势及机会分析报告PPT

导读&#xff1a;原文《》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 喜欢文章&#xff0c;您可以点赞评论转发本文&#xff0c;了解更多内容请私信&#xff1a;方…...

【JavaWeb】实训的长篇笔记(上)

JavaWeb的实训是学校的一门课程&#xff0c;老师先讲解一些基础知识&#xff0c;然后让我们自己开发一个比较简单的Web程序。可涉及的知识何其之多&#xff0c;不是实训课的 3 周时间可以讲得完的&#xff0c;只是快速带过。他说&#xff1a;重点是Web开发的流程。 我的实训草草…...

如何使用Docker安装AWVS?

前言 还记得很早的时候使用AWVS&#xff0c;还需要找位置&#xff0c;贴补丁&#xff0c;放文件&#xff0c;现在慢慢掌握Docker后发现&#xff0c;使用Docker去部署一些东西就很方便&#xff0c;当然也包括AWVS。 我们今天带大家通过Docker部署AWVS&#xff08;有中文哦&…...

vue命名规范

文件和文件夹的命名&#xff1a; 文件夹命名&#xff1a; Vue 项目中通常可以根据功能或页面来划分文件夹。例如&#xff0c;您可以为每个页面创建一个文件夹&#xff0c;并将相关的组件、样式和资源文件放在其中。文件夹的命名最好使用短横线分隔的小写字母&#xff08;kebab …...

第05天 SpringBoot自动配置原理

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;每天一个知识点 ✨特色专栏&#xff1a…...

AlphaZero能否从围棋和国际象棋飞跃到量子计算?

一项新的研究表明&#xff0c;DeepMind惊人的游戏算法AlphaZero可以帮助释放量子计算的力量和潜力。 自两年多前出现以来&#xff0c;AlphaZero一再证明了其快速学习能力&#xff0c;将自己提升到围棋&#xff0c;国际象棋和将棋&#xff08;日本象棋&#xff09;的特级大师级别…...

进程切换

进程切换 上下文切换上下文切换的消耗上下文切换与模式切换 对于通常的进程而言&#xff0c;其创建、撤销及要求由系统设备完成的IO操作&#xff0c;都是利用系统调用而进入内核&#xff0c;再由内核中的相应处理程序予以才完成的。进程切换同样是在内核的支持下实现的&#xf…...

ES踩坑记录之UNASSIGNED分片无法恢复

问题背景 换节点 我们线上有一套ES集群&#xff0c;三台机器&#xff0c;共运行了6个节点。一直在线上跑了几个月也一直没出什么问题。然而好巧不巧&#xff0c;就在昨天&#xff0c;集群中的3号节点磁盘出现故障&#xff0c;导致机器直接瘫痪。本来大家觉得问题不大&#xf…...

ubuntu更换国内apt源

ubuntu必备操作 1 更换apt镜像源 备份镜像 cp /etc/apt/sources.list /etc/apt/sources.list.bak查看自己ubuntu版本 # 查看自己的codename #查看自己的ubuntu版本[注意关注&#xff1a;DISTRIB_CODENAME&#xff0c;发行代号] cat /etc/*release# DISTRIB_CODENAMEcosmic …...

OpenCV-Python中的图像处理-视频分析

OpenCV-Python中的图像处理-视频分析 视频分析Meanshift算法Camshift算法光流Lucas-Kanade Optical FlowDense Optical Flow 视频分析 学习使用 Meanshift 和 Camshift 算法在视频中找到并跟踪目标对象: Meanshift算法 Meanshift 算法的基本原理是和很简单的。假设我们有一堆…...

STM32 CubeMX (第四步Freertos内存管理和CPU使用率)

STM32 CubeMX STM32 CubeMX &#xff08;第四步Freertos内存管理和CPU使用率&#xff09; STM32 CubeMX一、STM32 CubeMX设置时钟配置HAL时基选择TIM1&#xff08;不要选择滴答定时器&#xff1b;滴答定时器留给OS系统做时基&#xff09;使用STM32 CubeMX 库&#xff0c;配置Fr…...

题解 | #1012.Equalize the Array# 2023杭电暑期多校10

1012.Equalize the Array 签到 题目大意 定义一个数组的 m o d e mode mode 是其中出现次数最多的数字&#xff08;可不唯一&#xff09; 给定一个数组 a a a &#xff0c;每次操作可以选定其一个 m o d e mode mode 并使数组中所有与之相等的元素 1 1 1 问任意次操作后…...

UE4/5C++多线程插件制作(二十一、使用)

目录 DemoPawn.h DemoPawn.cpp 会出现的bug 插件 相关的插件制作在上一节已经完成了。 具体的使用方式在第0章已经写了,get之后去绑定即可。 而后笔者做了一个接口,具体的绑定方式也就在这个接口里面。 接下来最重要的是进行使用,对此我做了一个与蓝图相关的接口,里…...

【C#】关于?的用法

1、可空类型修饰符&#xff08;&#xff1f;&#xff09; 如&#xff1a; int? x null;//可空类型默认值都是null&#xff0c;而值类型如int默认值为0、bool默认值为false等 bool? result true;2、三目运算符&#xff08;?&#xff1a;&#xff09; 如&#xff1a; bool…...

linux——mysql的高可用MHA

目录 一、概述 一、概念 二、组成 三、特点 四、工作原理 二、案例 三、构建MHA 一、基础环境 二、ssh免密登录 三、主从复制 master slave1 四、MHA安装 一、环境 二、安装node 三、安装manager 一、概述 一、概念 MHA&#xff08;MasterHigh Availability&a…...

【学习日记】【FreeRTOS】空闲任务与阻塞延时

写在前面 本文是基于野火 RTOS 教程对空闲任务和阻塞延时的详解。 一、什么是任务中的阻塞延时 说到阻塞延时&#xff0c;笔者的第一反应就是在单片机的 while 循环中&#xff0c;使用一个 for 循环不断递减一个大数&#xff0c;通过 CPU 不断执行一条指令的耗时进行延时。这…...

衣服材质等整理(时常更新)

参考文章&图片来源 https://zhuanlan.zhihu.com/p/390341736 00. 天然纤维 01. 化学纤维 02. 聚酯纤维&#xff08;即&#xff0c;涤纶&#xff09; 一种由有机二元酸和二元醇通过化学缩聚制成的合成纤维。具有出色的抗皱性和保形性&#xff0c;所制衣物在穿着过程中不容…...

电子商务环境下旅游价值链

迈克尔 ・ 波特(Michael E. Porter)在其《竞争优势》一书中提出了“价值链” 的概念&#xff0c;并认为一家企业最核心的竞争优势在于对价值链的设计。虽然迈克尔 ・ 波 特提出的价值链主要是针对企业内部的价值链&#xff0c;但他视价值链为一系列连续完成的 活动&#xff…...

spring源码分析bean的生命周期(下)

doGetBean()执行过程 createBean()执行过程 一、DependsOn注解 spring创建对象之前会判断类上是否加了DependsOn注解&#xff0c;加了会遍历然后会添加到一个map中&#xff0c;spring会先创建DependsOn注解指定的类 二、spring类加载器 在合并BeanDefinition&#xff0c;确定…...

完美解决Github提交PR后报错:File is not gofumpt-ed (gofumpt)

问题阐述 最近在Github上提交PR后&#xff0c;遇到了这么一个问题&#xff1a;golangci-lint运行失败&#xff0c;具体原因是File is not gofumpt-ed (gofumpt)。 名词解释 golangci-lint&#xff1a; golangci-lint 是Go语言社区中常用的代码质量检查工具&#xff0c;它可以…...

pytorch3d成功安装

一、pytorch3d是什么&#xff1f; PyTorch3D的目标是帮助加速深度学习和3D交叉点的研究。3D数据比2D图像更复杂&#xff0c;在从事Mesh R-CNN和C3DPO等项目时&#xff0c;我们遇到了一些挑战&#xff0c;包括3D数据表示、批处理和速度。我们开发了许多有用的算子和抽象&#xf…...

【vue3】同个页面引入多个图表组件实现自适应的方法

首先说明&#xff0c;此方案仅针对vue3项目在同一个页面引入了多个图表组件&#xff0c;因为我发现不能框架不同的引入&#xff0c;resize的写法还不同 window.addEventListener("resize", function() {...// 在此处重新调用即可 }以下是具体写法&#xff1a; 循环…...

一文了解汽车芯片的分类及用途介绍

汽车芯片按其功能可分为控制类&#xff08;MCU和AI芯片&#xff09;、功率类、传感器和其他&#xff08;如存储器&#xff09;四种类型。市场基本被国际巨头所垄断。人们常说的汽车芯片是指汽车里的计算芯片&#xff0c;按集成规模可分为MCU芯片和AI芯片&#xff08;SoC芯片&am…...

Linux0.11内核源码解析-truncate.c

truncate文件只要实现释放指定i节点在设备上占用的所有逻辑块&#xff0c;包括直接块、一次间接块、二次间接块。从而将文件节点对应的文件长度截为0&#xff0c;并释放占用的设备空间。 索引节点的逻辑块连接方式 释放一次间接块 static void free_ind(int dev,int block) {…...

LED驱动型IC芯片的原理介绍

一、LED驱动器是什么 LED驱动器&#xff08;LED Driver&#xff09;&#xff0c;是指驱动LED发光或LED模块组件正常工作的电源调整电子器件。由于LED PN结的导通特性决定&#xff0c;它能适应的电源电压和电流变动范围十分狭窄&#xff0c;稍许偏离就可能无法点亮LED或者发光效…...

VLAN实验

实验题目如下&#xff1a; 实验拓扑如下&#xff1a; 实验要求如下&#xff1a; 【1】PC1/3的接口均为access模式&#xff0c;且属于van2&#xff0c;在同一网段 【2】PC2/4/5/6的IP地址在同一网段&#xff0c;与PC1/3不在同一网段 【3】PC2可以访问4/5/6&#xff0c;PC4不能…...

Qt应用开发(基础篇)——高级纯文本窗口 QPlainTextEdit

一、前言 QPlainTextEdit类继承于QAbstractScrollArea&#xff0c;QAbstractScrollArea继承于QFrame&#xff0c;是Qt用来显示和编辑纯文本的窗口。 滚屏区域基类https://blog.csdn.net/u014491932/article/details/132245486?spm1001.2014.3001.5501框架类QFramehttps://blo…...

三维可视化平台有哪些?Sovit3D可视化平台怎么样?

随着社会经济的发展和数字技术的进步&#xff0c;互联网行业发展迅速。为了适应新时代社会发展的需要&#xff0c;大数据在这个社会经济发展过程中随着技术的进步而显得尤为重要。同时&#xff0c;大数据技术的快速发展进程也推动了可视化技术的飞速发展&#xff0c;国内外各类…...

Xxl-job安装部署以及SpringBoot集成Xxl-job使用

1、安装Xxl-job&#xff1a; 可以使用docker拉取镜像部署和源码编译两种方式&#xff0c;这里选择源码编译安装。 代码拉取地址&#xff1a; https://github.com/xuxueli/xxl-job/tree/2.1.2 官方开发文档&#xff1a; https://www.xuxueli.com/xxl-job/#%E3%80%8A%E5%88%…...