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!

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

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

相关文章

react-vite-antd环境下新建项目

vite 创建一个react项目 1. 安装vite并创建一个react项目1. 我使用的 yarn安装,基本配置项目名字, 框架react ,js2. cd vite-react进入项目目录安装node包并启动项目 2. 安装引入Ant Design引入依赖(我用的yarn,没有安装的也可以使…

视频汇聚/视频云存储/视频监控管理平台EasyCVR添加萤石云设备详细操作来啦!

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

css伪元素实现li列表圆点相连+锚点跳转悬浮窗实现

实现效果&#xff1a; html代码&#xff1a; <div class"sidenav"><ul class"nav-text progressbar"><!-- data-target的值对应要跳转的模块的id --><li data-target"module1"><div class"text">锚点…

Effective Java 案例分享(九)

46、使用无副作用的Stream 本章节主要举例了Stream的几种用法。 案例一&#xff1a; // Uses the streams API but not the paradigm--Dont do this! Map<String, Long> freq new HashMap<>(); try (Stream<String> words new Scanner(file).tokens()) …

Java创建对象的几种方式

在Java中&#xff0c;对象是程序中的一种基本元素&#xff0c;它通过类定义和创建。本篇教程旨在介绍Java中创建对象的几种方式&#xff0c;包括使用new关键字、反射、clone、反序列化等方式。 使用new关键字创建对象 在Java中&#xff0c;最常用的创建对象方式是使用new关键…

linux学习(文件描述符)[13]

所以fork的时候函数执行完毕&#xff0c;但是数据还在缓冲区中未刷新。 所以会有父子两份数据 在fork&#xff08;&#xff09;之前ffush&#xff08;&#xff09;&#xff08;c语言的接口&#xff0c;刷新缓冲区&#xff09;fflush(stdout)&#xff0c;就不会有重复 缓冲区的…

Trie树(前缀树)的实现与应用

Trie树&#xff0c;也被称为前缀树&#xff0c;是一种用于处理字符串的数据结构。它可以高效地进行字符串的插入、删除和搜索操作&#xff0c;并且能够快速找到具有相同前缀的字符串。本篇博客将详细介绍Trie树的实现原理和应用场景&#xff0c;并给出Java代码示例。 Trie树的…

MyBatis的入门级环境搭建及增删改查,详细易懂

目录 一.mybatis的简介 二.MyBatis的环境搭建 2.1 导入pom依赖 2.2 数据库文件导入连接 2.3 修改web.xml文件 2.4 安装插件 2.5 配置文件 2.5.1 mybatis.cfg.xml文件 2.5.2 generatorConfig.xml文件 2.6 最后测试生成代码 三.MyBatis的增删改查 3.1 写service类&#xff…

Linux命令200例:nc非常有用的网络工具(常用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

【LVS】3、LVS+Keepalived群集

为什么用它&#xff0c;为了做高可用 服务功能 1.故障自动切换 2.健康检查 3.节点服务器高可用-HA Keepalived的三个模块&#xff1a; core&#xff1a;Keepalived的核心&#xff0c;负责主进程的启动、维护&#xff1b;调用全局配置文件进行加载和解析 vrrp&#xff1a;实…

matlab使用教程(16)—图论中图的定义与修改

1.修改现有图的节点和边 此示例演示如何使用 addedge 、 rmedge 、 addnode 、 rmnode 、 findedge 、 findnode 及 subgraph 函数访问和修改 graph 或 digraph 对象中的节点和/或边。 1.1 添加节点 创建一个包含四个节点和四条边的图。s 和 t 中的对应元素用于指定每条…

使用 MBean 和 日志查看 Tomcat 线程池核心属性数据

文章目录 CustomTomcatThreadPoolMBeanCustomTomcatThreadPool CustomTomcatThreadPoolMBean com.qww.config;public interface CustomTomcatThreadPoolMBean {String getStatus(); }CustomTomcatThreadPool package com.qww.config;import com.alibaba.fastjson.JSON; impor…

三本书与三场发布会,和鲸社区重新定义编程类书籍从阅读到实践新体验

当 AI 开发者社区配备 AI 基础设施开发平台工具时&#xff0c;它还能做什么&#xff1f; 答案是&#xff1a;过去半年&#xff0c;和鲸社区凭借在气象、医学、社科等垂直领域的长期积累以及多方伙伴的支持&#xff0c;联合举办了三场新书发布会——从 Python 到 R 语言 、从气…

Midjourney Prompt 提示词速查表 v5.2

Midjourney 最新的版本更新正不断推出令人兴奋的新功能。这虽然不断扩展了我们的AI绘图工具箱&#xff0c;但有时也会让我们难以掌握所有实际可以使用的功能和参数。 针对此问题, 小编整理了 "Midjourney Prompt 提示词速查表"&#xff0c;这是一个非常方便的 Midjo…

Java“牵手“拼多多商品详情页面数据获取方法,拼多多API实现批量商品数据抓取示例

拼多多商城是一个网上购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取拼多多商品详情数据&#xff0c;您可以通过开放平台的接口或者直接访问拼多多商城的网页来获取商品详情信息。以下是两种常用方法的介绍&#xff1a;…

Linux:shell脚本数组和脚本免交互

目录 一、shell数组的定义 二、定义数组的方式 &#xff08;1&#xff09;数组名(value1 value2 value3 value4 ...) &#xff08;2&#xff09;获取数组的长度 &#xff08;3&#xff09;获取数组下标对应的值 &#xff08;4&#xff09;数组的遍历 &#xff08;5&#x…

qsort函数详解

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解qsort函数&#xff0c;如果你觉得我写的不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 文章目录 一. qsort函数参数详解1.数组首元素地址base2.数组的元素个数num和元素所占内存空间大小w…

ThreeJS——在3D地球上标记中国地图板块

Threejs3D地球标记中国地图位置 先看效果 地球预览视频效果 用到的库 TweenJS (动画库)用来做相机转场的动画Jquery(这里只用到一个 each 循环方法&#xff0c;可以使用 js 去写)ThreeJS (3D 地球制作)100000.json(全国城市经纬度)d3.v6.js用来设置平面转3D效果(本来考虑做成…

深入解析IDS/IPS与SSL/TLS和网络安全

目录 防火墙 IDS IPS DMZ VPN VPS SSL/TLS 动态IP 静态IP 防火墙 防火墙是一种网络安全设备&#xff0c;用于监控和控制网络流量&#xff0c;保护网络免受未经授权的访问、恶意攻击和威胁。防火墙可以基于规则进行数据包过滤&#xff0c;允许或阻止特定类型的流量通过…

Lead-Lag控制器形式

对于Lead-Lag&#xff08;超前—滞后&#xff09;&#xff0c;有的地方叫做控制器 Controller&#xff0c;有的地方叫补偿器 Compensator&#xff0c;有的地方叫滤波器 Filter&#xff0c;都是一个东西。 Lead-Lag也有几种不同的形式&#xff0c;一种是 G c ( s ) 1 a T s 1…