GPT带我学-设计模式-模板模式
1 请你给我介绍一下设计模式中的模板模式
模板模式是一种行为设计模式,它定义了一个算法的骨架,将一些步骤的具体实现延迟到子类中。模板模式允许子类重新定义算法的某些特定步骤,而不需要改变算法的结构。
模板模式由以下几个角色组成:
- 抽象类(Abstract Class):抽象类定义了一个模板方法,该方法定义了算法的骨架,包含了一系列抽象方法或可选的具体实现方法。抽象类可以提供默认的实现,也可以作为模板方法的一部分使用。
- 具体类(Concrete Class):具体类实现了抽象类中定义的抽象方法,完成了算法中的具体步骤。
模板模式的工作流程如下:
- 定义一个抽象类,其中包含一个模板方法。
- 在模板方法中定义算法的骨架,即一系列的步骤。
- 将某些具体步骤的实现延迟到子类中,通过定义抽象方法或可选的具体实现方法来实现。
- 具体子类继承抽象类,并实现其中的抽象方法或可选的具体实现方法,完成算法中的具体步骤。
- 客户端通过调用抽象类的模板方法来使用模板模式。
模板模式的优点包括:
- 通过定义算法的骨架,使算法的结构更加清晰明了。
- 提供了一种方便的扩展算法的方式。只需继承抽象类并实现相应的方法即可。
- 将公共的代码抽取到父类中,避免了代码的重复。
模板模式的缺点包括:
- 可能会导致类的数量增加:因为模板模式需要定义抽象类和具体类,所以可能会导致类的数量增加,特别是当有多个变种的算法时。
- 可能会引入不必要的复杂性:模板模式将算法的具体实现分散到不同的类中,可能会增加代码的复杂性和理解难度。
- 不太灵活:因为模板模式的算法骨架是固定的,所以对于需要大量变动的算法,模板模式可能不太适用。如果有太多的不同步骤和变种,维护和使用模板模式可能会变得困难。
- 可能会限制了代码的扩展性:因为算法的结构是固定的,所以对于需要频繁变动的部分,可能需要修改抽象类的结构,这可能会影响到其他使用该模板的类。
总结来说,模板模式通过定义算法的骨架和将具体步骤的实现延迟到子类中,提供了一种方便的算法设计和扩展方式,可以提高代码的重用性和可维护性。
2 请你用java举一个实际一点的例子
好的,下面是一个使用模板模式的java示例:
在下面的示例中,抽象类 Game 定义了一个模板方法 play(),它定义了一个游戏的骨架,包含了初始化游戏、开始游戏和结束游戏的步骤。具体的游戏类 Football 和 Basketball 继承抽象类 Game,并实现了抽象方法,在不同的具体类中完成了对应的具体步骤。
abstract class Game {abstract void initialize();abstract void startPlay();abstract void endPlay();// 模板方法public final void play() {// 初始化游戏initialize();// 开始游戏startPlay();// 结束游戏endPlay();}
}class Football extends Game {@Overridevoid initialize() {System.out.println("Football Game Initialized! Start playing.");}@Overridevoid startPlay() {System.out.println("Football Game Started. Enjoy the game!");}@Overridevoid endPlay() {System.out.println("Football Game Finished!");}
}class Basketball extends Game {@Overridevoid initialize() {System.out.println("Basketball Game Initialized! Start playing.");}@Overridevoid startPlay() {System.out.println("Basketball Game Started. Enjoy the game!");}@Overridevoid endPlay() {System.out.println("Basketball Game Finished!");}
}public class TemplatePatternExample {public static void main(String[] args) {Game footballGame = new Football();footballGame.play();System.out.println("------------------------------");Game basketballGame = new Basketball();basketballGame.play();}
}
通过创建不同的具体游戏对象,然后调用它们的 play() 方法,我们可以按照固定的游戏流程来玩足球游戏和篮球游戏。输出结果如下:
Football Game Initialized! Start playing.
Football Game Started. Enjoy the game!
Football Game Finished!
------------------------------
Basketball Game Initialized! Start playing.
Basketball Game Started. Enjoy the game!
Basketball Game Finished!
这个例子展示了模板模式的应用,通过定义抽象类的模板方法,将游戏的算法骨架固定下来,并将具体的步骤实现延迟给子类,从而实现了游戏的统一流程管理,同时也提供了扩展游戏的方式。
3 模板模式有几种形式
模板模式有两种常见的形式:
-
基本的模板模式(Basic Template Pattern):基本的模板模式是指通过抽象类定义算法的骨架,将某些步骤的具体实现延迟到子类中。抽象类中的模板方法定义了算法的骨架,包含了一系列的抽象方法或具体实现方法。子类继承抽象类,并实现其中的抽象方法,完成算法中的具体步骤。
-
钩子方法模式(Hook Method Pattern):钩子方法模式是基本的模板模式的扩展,它允许子类在父类的算法中插入或不插入一些特定的行为。钩子方法是指在抽象类中提供一个空实现或默认返回值的抽象方法,子类可以选择性地覆盖或使用这些钩子方法,按需插入自己的行为。
这两种形式都遵循了模板模式的基本原则,即通过抽象类定义算法的骨架,将某些具体步骤的实现延迟到子类中,以实现代码重用和扩展的目的。在实际应用中,根据需要选择合适的形式来设计和实现模板模式。
4 那请你用钩子方法模式修改上面游戏的代码
好的,以下是使用钩子方法模式修改上述游戏代码的示例:
abstract class Game {abstract void initialize();abstract void startPlay();abstract void endPlay();// 钩子方法,允许子类在父类的算法中插入特定行为protected boolean additionalPlay() {return true;}// 模板方法public final void play() {initialize();startPlay();// 在这里插入额外的行为if (additionalPlay()) {playExtra();}endPlay();}// 钩子方法protected void playExtra() {// 默认空实现}
}class Football extends Game {@Overridevoid initialize() {System.out.println("Football Game Initialized! Start playing.");}@Overridevoid startPlay() {System.out.println("Football Game Started. Enjoy the game!");}@Overridevoid endPlay() {System.out.println("Football Game Finished!");}@Overrideprotected void playExtra() {System.out.println("Football Game: Play some extra time.");}
}class Basketball extends Game {@Overridevoid initialize() {System.out.println("Basketball Game Initialized! Start playing.");}@Overridevoid startPlay() {System.out.println("Basketball Game Started. Enjoy the game!");}@Overridevoid endPlay() {System.out.println("Basketball Game Finished!");}
}public class TemplatePatternExample {public static void main(String[] args) {Game footballGame = new Football();footballGame.play();System.out.println("------------------------------");Game basketballGame = new Basketball();basketballGame.play();}
}
在这个示例中,我们在抽象类 Game 中添加了一个钩子方法 additionalPlay() 和一个默认的钩子方法 playExtra()。在模板方法 play() 中,我们在适当的时机使用了钩子方法 additionalPlay() 来决定是否执行额外的行为。在 Football 类中,我们覆盖了默认的钩子方法 playExtra() 来执行一些额外的操作。
当运行这个示例时,输出结果如下
Football Game Initialized! Start playing.
Football Game Started. Enjoy the game!
Football Game: Play some extra time.
Football Game Finished!
------------------------------
Basketball Game Initialized! Start playing.
Basketball Game Started. Enjoy the game!
Basketball Game Finished!
可以看到,在具体游戏类 Football 中,在运行模板方法 play() 时,额外的钩子方法 playExtra() 被调用了。而在具体游戏类 Basketball 中,并没有对钩子方法进行覆盖,所以默认的行为为空。
通过使用钩子方法模式,我们可以在父类的算法中插入特定的行为,通过选择性地覆盖钩子方法,在子类中自定义额外的操作。这种方式增强了模板方法的灵活性和可扩展性。
5 通常用在什么场景
模板模式通常适用于以下场景:
算法的整体流程是固定的,但某些步骤的具体实现可能会有所不同。通过模板模式,可以将整体流程封装在一个模板方法中,将具体实现延迟到子类中。
多个类具有相似的行为,但实现细节不同。通过模板模式,可以将共同的行为抽象为父类,将不同的实现细节委托给子类。
需要一种代码复用和扩展方式,以避免代码的重复。通过提供模板方法和抽象方法,可以在不同的子类中实现具体细节,实现代码的重用和扩展。
一些常见的应用场景包括:
框架或库的设计:框架或库通常会定义一些通用的算法或流程,供用户来实现具体的细节。模板模式可以将通用的算法骨架封装在父类中,用户可以通过实现抽象方法来定制化具体实现。
数据库访问:数据库访问通常包含一些通用的操作流程,如连接数据库、执行SQL语句、处理结果等。模板模式可以将这些通用流程封装在父类中,具体的数据库操作细节委托给子类。
Web开发中的请求处理:在Web开发中,处理请求通常包含一些通用的步骤,如请求解析、数据验证、业务逻辑处理、结果响应等。模板模式可以将这些通用步骤封装在父类中,将具体的处理细节留给子类实现。
总之,模板模式适用于任何需要固定算法框架,并通过子类实现具体细节的情况。它可以提高代码的复用性和扩展性,并确保整体流程的一致性。
总结
模板模式是一种行为型的设计模式,所以就是对行为的控制。其实质就是用抽象方法固定了流程,每个流程的具体实现交给其子类实现。从而统一流程。
相关文章:
GPT带我学-设计模式-模板模式
1 请你给我介绍一下设计模式中的模板模式 模板模式是一种行为设计模式,它定义了一个算法的骨架,将一些步骤的具体实现延迟到子类中。模板模式允许子类重新定义算法的某些特定步骤,而不需要改变算法的结构。 模板模式由以下几个角色组成&…...
Windows下调试UEFI程序:Visual Studio调试
以edk2\MdeModulePkg\Application\HelloWorld这个项目作为调试目标。 1. 使用VS2017建立Makefile工程 VS2017, 新建 project,取名X64dbg_vs。 Visual C > Other > Makefile Project, 注意项目路径为HelloWord程序路径。 随便填写config中的字符串ÿ…...
Vue中监听路由参数变化的几种方式
目录 一. 路由监听方式: 通过 watch 进行监听 1. 监听路由从哪儿来到哪儿去 2. 监听路由变化获取新老路由信息 3. 监听路由变化触发方法 4. 监听路由的 path 变化 5. 监听路由的 path 变化, 使用handler函数 6. 监听路由的 path 变化,触发method…...
angular——子组件如何接收父组件的动态传值
开发过程中,父组件给子组件传值的情况很常见,今天我们就来聊聊父组件给子组件传值可能会发生哪些意外,什么情况下子组件无法接收到父组件最新的传值; 传值情况: 基本数据类型:父组件给子组件传递 基本数据…...
php 桥接模式
一,桥接模式,是结构设计模式的一种,其将抽象部分和实现部分分离开来,使两部分可以独立的进行修改,提高系统的灵活性。在桥接模式中,需要定义一个抽象类和一个实现类,通过将实现类注入到抽象类中…...
Android 13 Hotseat定制化修改——004 hotseat布局位置
目录 一.背景 二.原生hotseat布局位置 三.修改Hotseat布局位置 一.背景 由于需求是需要自定义修改Hotseat,所以此篇文章是记录如何自定义修改hotseat的,应该可以覆盖大部分场景,修改点有修改hotseat布局方向,hotseat图标数量,hotseat图标大小,hotseat布局位置,hotseat…...
海外版金融理财系统源码 国际投资理财系统源码 项目投资理财源码
海外版金融理财系统源码 国际投资理财系统源码 项目投资理财源码...
洛谷P1162 - 填涂颜色
题目描述 由数字 0 0 0 组成的方阵中,有一任意形状闭合圈,闭合圈由数字 1 1 1 构成,围圈时只走上下左右 4 4 4 个方向。现要求把闭合圈内的所有空间都填写成 2 2 2。例如: 6 6 6\times 6 66 的方阵( n 6 n6 n6&…...
设计模式十一:外观模式(Facade Pattern)
外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口,用于访问系统中的一组复杂子系统。外观模式通过将复杂子系统的接口封装在一个高层接口中,简化了客户端与子系统之间的交互,使得客户…...
GIS和倾斜摄影的关系?
GIS(地理信息系统)和倾斜摄影是两种在地理空间数据处理和分析中扮演重要角色的技术。但是我们总是会分不清二者,本文就带大家从不同角度了解二者之间的关系。 概念 GIS是一种用来捕获、存储、分析和展示地理空间数据的技术,它可以…...
【CI/CD】图解六种分支管理模型
图解六种分支管理模型 任何一家公司乃至于一个小组织,只要有写代码的地方,就有代码版本管理的主场,初入职场,总会遇到第一个拦路虎 git 管理流程,但是每一个企业似乎都有自己的 git 管理流程,倘若我们能掌握…...
LeetCode105. 从前序与中序遍历序列构造二叉树
105. 从前序与中序遍历序列构造二叉树 文章目录 [105. 从前序与中序遍历序列构造二叉树](https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/)一、题目二、题解 一、题目 给定两个整数数组 preorder 和 inorder ,其中 preo…...
编码技巧——Sentinel的blockHandler与fallback
本文介绍Sentinel的blockHandler与fallback的区别,背景是:发生限流时,配置的sentinel的blockhandler没有生效而fallback生效了;排查原因,从而给出Sentinel配置异常降级和限流降级的代码写法; 在查看源码前…...
最新成果展示:GaN基Micro-LED热学模型数据库的开发及应用
由于GaN基Micro-LED表面积-体积比增加,其在热学方面的性质有别于大尺寸的LED,如缺陷复合导致的热效应将在发光区域中产生诸多“热”点,导致发光波长不均匀,这将影响后期显示系统的成像稳定性。针对上述问题,天津赛米卡…...
【Vue3】动态组件
动态组件的基本使用 动态组件(Dynamic Components)是一种在 Vue 中根据条件或用户输入来动态渲染不同组件的技术。 在 Vue 中使用动态组件,可以使用 元素,并通过 is 特性绑定一个组件的名称或组件对象。通过在父组件中改变 is 特…...
Java超级玛丽小游戏制作过程讲解 第五天 创建并完成常量类04
//加载障碍物 try {obstacle.add(ImageIO.read(new File(path"brick.png")));obstacle.add(ImageIO.read(new File(path"soil_up.png")));obstacle.add(ImageIO.read(new File(path"soil_base.png"))); } catch (IOException e) {e.printStackTr…...
设置浏览器兼容
浏览器兼容 css兼容 cursor定义手型 Firefox不支持hand,IE支持pointer 解决方法:统一使用pointercss透明 IE:filter:progid:DXImageTransform.Microsoft.Alpha(style0,opacity60) Firefox:opacity:0.6 解决…...
Java # List
ArrayList<>() import java.util.ArrayList; // 引入 ArrayList 类ArrayList<E> objectName new ArrayList<>(); // 初始化 常用方法 方法描述add()将元素插入到指定位置的 arraylist 中addAll()添加集合中的所有元素到 arraylist 中clear()删除 arrayl…...
git原理与使用
目录 引入基本操作分支管理远程操作标签管理 引入 假设你的老板要你设计一个文档,当你设计好了,拿给他看时,他并不是很满意,就要你拿回去修改,你修改完后,再给他看时,他还是不满意,…...
【C语言题解】将一句话的单词进行倒置,标点不倒置。
题目描述:将一句话的单词进行倒置,标点不倒置。比如 “I like beijing.”,经过处理后变为:“beijing. like I”。 文章目录 原题目题目描述:输入描述:输出描述:题目链接: 整体思路分…...
Shinkai Node:构建自主AI Agent的去中心化操作系统内核
1. 项目概述:Shinkai Node 是什么,以及它为何值得关注最近在跟一些做AI应用开发的朋友聊天,发现大家普遍面临一个痛点:如何让AI Agent(智能体)真正“活”起来,拥有持续的记忆、自主的行动能力&a…...
红外对射传感器实战指南:从原理到Arduino/CircuitPython应用
1. 项目概述红外对射传感器,也叫红外遮断传感器,是我在自动化项目和互动装置里用得最多的基础传感器之一。它原理简单直接,但用好了能解决很多实际问题,比如统计人流、检测传送带上的物品、制作一个简单的防盗报警器,或…...
基于节点电价的电网对电动汽车接纳能力评估模型研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Windows11下DOSBox从零到精通的完整配置与实战指南
1. 为什么要在Windows11上使用DOSBox? 很多年轻朋友可能都没见过DOS系统长什么样。作为上世纪80年代到90年代的主流操作系统,DOS虽然界面简陋,但它孕育了无数经典软件和游戏。直到今天,学习汇编语言、运行老式工业控制程序、怀旧经…...
RK3588 NPU部署YOLOv8全流程:从ONNX转换到板端C++/Python推理优化
1. 项目概述:为什么要在RK3588上部署YOLOv8?最近在边缘计算项目里,我遇到了一个典型的需求:客户需要在本地设备上实时分析摄像头画面,识别特定物体并分割出它们的轮廓,同时要求设备功耗低、体积小、成本可控…...
在STM32F103上用FreeRTOS模拟I2C,为什么我劝你放弃硬件I2C?
为什么在STM32F103上使用FreeRTOS时,模拟I2C比硬件I2C更靠谱? 如果你正在使用STM32F103开发项目,并且需要在FreeRTOS环境下实现I2C通信,那么这篇文章可能会改变你的技术选型决策。很多开发者初次接触STM32时,都会优先考…...
终极指南:SwiftUI-experiments中的粒子动画实现技巧与实战教程
终极指南:SwiftUI-experiments中的粒子动画实现技巧与实战教程 【免费下载链接】SwiftUI-experiments Examples with SwiftUI and other Apple frameworks that showcase various interactions, animations and more 项目地址: https://gitcode.com/gh_mirrors/sw…...
树莓派GPIO排针焊接与外壳组装全攻略:从焊接技巧到机械装配
1. 项目概述与核心价值如果你手头有一块树莓派,并且打算用它来驱动一个像Joy Bonnet这样的游戏手柄扩展板,或者任何其他需要直接插在GPIO排针上的HAT(硬件附加板),那么你迟早会面临一个非常具体且有点“劝退”的硬件关…...
2026届毕业生推荐的五大AI辅助论文方案解析与推荐
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 在当下这个信息呈现爆炸态势的时代里,内容所具备的价值越发突显出来。不管是企业…...
ARM架构计数器与定时器虚拟化技术详解
1. ARM架构中的计数器-定时器虚拟化技术概述在现代虚拟化环境中,精确的时间管理是确保虚拟机性能和功能完整性的关键要素。ARMv8/v9架构通过一系列精心设计的系统寄存器和硬件特性,为hypervisor提供了强大的计数器与定时器虚拟化能力。这项技术允许每个虚…...
