设计模式行为型-模板模式
文章目录
- 一:模板方法设计模式概述
- 1.1 简介
- 1.2 定义和目的
- 1.3 关键特点
- 1.4 适用场景
- 二:模板方法设计模式基本原理
- 2.1 抽象类
- 2.1.1 定义和作用
- 2.1.2 模板方法
- 2.1.3 具体方法
- 2.2 具体类
- 2.2.1 定义和作用
- 2.2.2 实现抽象类中的抽象方法
- 2.2.3 覆盖钩子方法
- 三:模板方法设计模式实现步骤
- 3.1 创建抽象类
- 3.1.1 声明模板方法
- 3.1.2 定义具体方法
- 3.1.3 定义钩子方法
- 3.2 创建具体类
- 3.2.1 实现抽象类中的抽象方法
- 3.2.2 覆盖钩子方法
- 四:模板方法设计模式应用场景
- 4.1 实际案例背景介绍
- 4.2 设计模式解决方案
- 4.3 实现代码示例
- 五:模板方法设计模式应用注意事项
- 5.1 钩子方法的使用场景和注意事项
- 5.2 与其他设计模式的关系
- 5.3 使用建议和最佳实践
- 结语
一:模板方法设计模式概述
1.1 简介
模板方法设计模式是一种行为型设计模式,它定义了一个算法的骨架,在其中某些步骤由具体子类来实现。
1.2 定义和目的
模板方法设计模式通过将算法通用部分放在抽象类中,具体实现留给具体子类来完成,以提高代码的复用性和可维护性。
1.3 关键特点
- 模板方法:定义算法的骨架,其中某些步骤由具体子类来实现。
- 具体方法:抽象类中已经实现的方法,子类不能修改。
- 钩子方法:抽象类中定义的可选方法,具体子类选择性地覆盖,可以改变模板方法的行为。
1.4 适用场景
- 当算法有固定的结构或步骤,并且步骤之间存在关联性时,可以使用模板方法设计模式。
- 当需要在不同上下文中应用相似的算法时,可以使用模板方法设计模式。
- 当希望通过基类来控制子类的行为时,可以使用模板方法设计模式。
二:模板方法设计模式基本原理
2.1 抽象类
2.1.1 定义和作用
抽象类是模板方法设计模式的核心角色,它定义了模板方法和一系列抽象方法,描述算法的结构和步骤。
2.1.2 模板方法
模板方法是抽象类中定义的方法,描述算法的骨架。该方法通常是final类型的,以防止子类对其进行修改。
2.1.3 具体方法
具体方法是抽象类中已经实现的方法,子类不能修改。这些方法通常是模板方法所需要的辅助方法或公共方法。
2.2 具体类
2.2.1 定义和作用
具体类是抽象类的子类,负责实现抽象类中的抽象方法,完成算法的具体实现。
2.2.2 实现抽象类中的抽象方法
具体类需要实现抽象类中定义的抽象方法,完成算法的具体实现。
2.2.3 覆盖钩子方法
具体类可以选择性地覆盖抽象类中定义的钩子方法,以改变模板方法的行为。
三:模板方法设计模式实现步骤
3.1 创建抽象类
3.1.1 声明模板方法
在抽象类中声明模板方法,描述算法的骨架。通常将该方法设置为final类型,防止子类修改。
3.1.2 定义具体方法
在抽象类中定义具体方法,这些方法在模板方法中被调用。这些方法通常是私有或受保护的,不允许子类直接调用。
3.1.3 定义钩子方法
定义可选的钩子方法,根据需要提供默认实现或为空实现。具体子类可以选择性地覆盖这些方法以改变模板方法的行为。
3.2 创建具体类
3.2.1 实现抽象类中的抽象方法
创建具体类并实现抽象类中的抽象方法,完成算法的具体实现。
3.2.2 覆盖钩子方法
具体类可以选择性地覆盖抽象类中的钩子方法,以改变模板方法的行为。
四:模板方法设计模式应用场景
4.1 实际案例背景介绍
假设我们正在开发一个游戏,这个游戏中有多个角色,每个角色都有不同的行为和技能。我们需要设计一个通用的角色创建流程,以确保每个角色的创建过程都符合一定的规范和约束。这就是一个适用于模板方法设计模式的实际案例。
4.2 设计模式解决方案
我们可以使用模板方法设计模式来解决上述问题。首先,我们创建一个抽象类作为角色的基类,其中包含了一个模板方法用于控制角色的创建流程。具体的角色类继承这个抽象类,并实现其中的抽象方法来完成自己特定的行为和技能。
在抽象类中,我们可以定义一些公共的方法,比如角色的初始化方法、资源加载方法等,这些方法已经实现并且不允许子类修改。同时,我们也可以定义一些钩子方法,用于在角色创建的不同阶段插入一些额外的逻辑。
抽象类中的模板方法定义了角色的创建流程,它按照一定的顺序调用了一系列的具体方法和钩子方法。这些具体方法和钩子方法由具体的角色类来实现,根据不同的需求来完成具体的行为和技能。
通过使用模板方法设计模式,我们可以将公共的部分提取到抽象类中,实现了代码的复用和可维护性的提高。同时,具体的角色类也能够灵活地实现自己特定的行为和技能,满足了游戏中多样化的角色需求。
4.3 实现代码示例
下面是一个简单的实现代码示例,演示了如何使用模板方法设计模式来创建游戏角色:
// 抽象类:角色
public abstract class Character {// 模板方法:创建角色public final void createCharacter() {initialize(); // 初始化角色loadResources(); // 加载资源doSomething(); // 具体行为hookMethod(); // 钩子方法}// 具体方法:初始化角色private void initialize() {System.out.println("Initializing character...");}// 具体方法:加载资源private void loadResources() {System.out.println("Loading resources...");}// 抽象方法:具体行为protected abstract void doSomething();// 钩子方法:可选的逻辑protected void hookMethod() {// 默认为空实现,子类可选择性地覆盖}
}// 具体类:战士角色
public class WarriorCharacter extends Character {@Overrideprotected void doSomething() {System.out.println("Warrior is fighting!");}
}// 具体类:法师角色
public class MageCharacter extends Character {@Overrideprotected void doSomething() {System.out.println("Mage is casting spells!");}
}// 测试代码
public class Main {public static void main(String[] args) {Character warrior = new WarriorCharacter();warrior.createCharacter(); // 输出:Initializing character... Loading resources... Warrior is fighting!Character mage = new MageCharacter();mage.createCharacter(); // 输出:Initializing character... Loading resources... Mage is casting spells!}
}
在上面的示例中,Character
是抽象类,其中的 createCharacter()
方法是模板方法,控制了角色的创建流程。具体的角色类 WarriorCharacter
和 MageCharacter
继承了 Character
并实现了其中的抽象方法 doSomething()
,完成了自己特定的行为。最后,在 Main
类中测试了这两个具体的角色类的创建过程。
通过运行上述代码示例,你可以看到不同角色的创建流程遵循了模板方法定义的骨架,但同时具体的角色类可以根据自身的需求实现不同的行为和技能。这就是模板方法设计模式的应用。
五:模板方法设计模式应用注意事项
5.1 钩子方法的使用场景和注意事项
钩子方法是在模板方法设计模式中的一种特殊方法,它在抽象类中提供了一个默认的空实现,子类可以选择性地覆盖或扩展这个方法。钩子方法的主要作用是允许子类在模板方法的特定点插入自己的逻辑,以实现对算法的定制和扩展。
使用钩子方法可以使得模板方法更加灵活和可扩展,同时也可以避免在抽象类中定义过多的抽象方法,简化了子类的实现。
一般来说,钩子方法的使用场景包括但不限于以下几种情况:
- 选择性执行:某些步骤在特定条件下需要执行,而在其他条件下可以跳过,钩子方法可以判断这些条件并决定是否执行相应步骤。
- 扩展功能:在模板方法的特定点添加新的逻辑或功能,用于满足不同的需求。
- 改变顺序:通过覆盖或扩展钩子方法,改变模板方法中步骤的执行顺序。
在使用钩子方法时,需要注意以下几点:
- 钩子方法的命名:钩子方法应该具有描述性的、能够体现其作用的命名,以便子类理解和正确使用。
- 钩子方法的默认实现:钩子方法在抽象类中应该有一个默认的空实现,以保证子类可以选择是否覆盖它。
- 钩子方法的调用时机:钩子方法应该在适当的时机被调用,以确保它们的逻辑能够正确地插入到模板方法中。
5.2 与其他设计模式的关系
模板方法设计模式与其他设计模式之间存在一些关系和区别。下面是一些常见的与模板方法设计模式相关的设计模式:
- 工厂方法模式(Factory Method Pattern):工厂方法模式也是一种创建型设计模式,它将对象的创建延迟到子类中进行。在工厂方法模式中,模板方法用于定义对象的创建过程,具体的产品由子类来实现。可以说,工厂方法模式是模板方法设计模式在创建对象方面的一种应用。
- 策略模式(Strategy Pattern):策略模式用于封装一系列的算法,并使它们可以互相替换。在策略模式中,每个算法都是一个独立的类,而模板方法则是在抽象类中定义的一系列步骤。可以说,策略模式是模板方法设计模式在算法封装方面的一种应用。
需要注意的是,模板方法设计模式和以上提到的设计模式并不是相互排斥的关系,它们可以结合使用来解决复杂的问题。在实际开发中,根据具体的需求和场景选择合适的设计模式,能够更好地设计和实现高质量的代码。
5.3 使用建议和最佳实践
以下是一些使用模板方法设计模式的建议和最佳实践:
- 合理划分抽象类和具体类:抽象类应该包含公共的行为和模板方法,具体类应该实现自己特定的行为。
- 提取公共的方法和逻辑:将公共的方法和逻辑提取到抽象类中,以避免代码的重复和冗余。
- 明确模板方法的执行流程:定义好模板方法的执行顺序,并确保每个步骤的执行时机正确。
- 合理使用钩子方法:在需要灵活定制或扩展的地方使用钩子方法,但不要滥用。过多的钩子方法可能导致代码难以理解和维护。
- 考虑模板方法的可变性:模板方法应该具有一定的可变性,以便子类可以根据自身需要进行定制。但同时也要保持模板方法的稳定性和一致性。
结语
模板方法设计模式是一种行为设计模式,它通过定义一个算法的骨架,在抽象类中封装了算法的主要步骤,并使用抽象方法和钩子方法来实现可变的部分。这种设计模式使得算法的结构保持稳定,而具体的实现细节可以由子类提供。
模板方法设计模式的优势在于:
- 提高代码复用性:将共同的代码逻辑封装在抽象类中,可以在不同的子类中共享使用,避免了重复编写相似的代码。
- 简化子类实现:通过将算法中的可变部分定义为抽象方法,子类只需要关注自己特定的实现细节,从而简化了子类的实现。
- 提供扩展点:通过钩子方法,允许子类在特定的执行点插入自己的逻辑,以实现对算法的定制和扩展。
然而,在使用模板方法设计模式时也需要考虑一些因素和注意事项:
- 需要明确模板方法的执行流程和步骤顺序,确保每个步骤的执行时机正确。
- 钩子方法应该有默认的空实现,以保证子类可以选择是否覆盖它。
- 合理使用钩子方法,不要过度使用,避免引入不必要的复杂性。
- 钩子方法的命名应该具有描述性,以便子类理解和正确使用。
相关文章:

设计模式行为型-模板模式
文章目录 一:模板方法设计模式概述1.1 简介1.2 定义和目的1.3 关键特点1.4 适用场景 二:模板方法设计模式基本原理2.1 抽象类2.1.1 定义和作用2.1.2 模板方法2.1.3 具体方法 2.2 具体类2.2.1 定义和作用2.2.2 实现抽象类中的抽象方法2.2.3 覆盖钩子方法 …...

9.3.tensorRT高级(4)封装系列-自动驾驶案例项目self-driving-车道线检测
目录 前言1. 车道线检测总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记。 本次课程学习 tensorRT 高级-自动驾驶案例项目self-driving-车道…...

django.core.exceptions.AppRegistryNotReady: Apps aren‘t loaded yet.
运行django测试用例报错django.core.exceptions.AppRegistryNotReady: Apps arent loaded yet. 解决:在测试文件上方加上 django.setup() django.setup()是Django框架中的一个函数。它用于在非Django环境下使用Django的各种功能、模型和设置。 在常规的Django应用…...

【C#】C#调用进程打开一个exe程序
文章目录 一、过程二、效果总结 一、过程 新建WinForm程序,并写入代码,明确要调用的程序的绝对路径(或相对路径)下的exe文件。 调用代码: 这里我调用的另一个程序的路径是: F:\WindowsFormsApplication2…...

宝塔面板定时监控和重启MySQL数据库(计划任务)
往期教程 如果还有不了解宝塔面板怎么使用的小伙伴,可以看下我总结的系列教程,保证从新手变老鸟: 【建站流程科普】 个人和企业搭建网站基本流程及六个主要步骤常见的VPS主机运维面板汇总—网站运维面板云服务器,VPS࿰…...

Beats:安装及配置 Metricbeat (二)- 8.x
这篇文章是继文章 “Beats:安装及配置 Metricbeat (一)- 8.x” 的续篇。你可以先阅读之前的那篇文章再继续阅读这篇文章。我们在这篇文章中继续之前的探讨。 使用 fingerprint 来代替证书 在实际的使用中,我们需要从 Elasticsear…...

Redis之哨兵模式解读
目录 基本介绍 单哨兵模式 多哨兵模式 哨兵的本质 配置哨兵模式 故障恢复原理 哨兵监控工作流程 哨兵模式缺点 基本介绍 当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多…...

题目:2644.找出可整除性得分最大的整数
题目来源: leetcode题目,网址:2644. 找出可整除性得分最大的整数 - 力扣(LeetCode) 解题思路: 遍历计算即可。 解题代码: class Solution {public int maxDivScore(int[] nums, int[] di…...

报错:axios 发送的接口请求 404
axios 发送的接口请求 404 一、问题二、分析 一、问题 二、分析 axios 发送的接口请求 404,根本没有把接口信息发送到后端,这个时候你可以查看检查一下自己的接口名字,或让后端配合换一个接口名字再发送一次接口请求...

三年前端还不会配置Nginx?刷完这篇就够了
什么是Nginx Nginx是一个开源的高性能HTTP和反向代理服务器。它可以用于处理静态资源、负载均衡、反向代理和缓存等任务。Nginx被广泛用于构建高可用性、高性能的Web应用程序和网站。它具有低内存消耗、高并发能力和良好的稳定性,因此在互联网领域非常受欢迎。 为…...

blender 场景灯光基础设置
在 blender 中,打光分为两个部分,一个是世界光,一个是场景光; 世界光: 世界光:在 Blender 中,世界光指的是用于设置场景整体照明的环境光。它可以通过调整颜色、强度、阴影等参数来影响场景的…...

如何查看 SQLyog 中数据库连接信息中的密码
SQLyog 数据库连接信息中的密码无法选择明文展示,也无法复制 可以将数据库连接信息导出到文本查看明文密码 工具--》导入/导出连接详情:...

【SpringSecurity】八、集成图片验证码
文章目录 1、生成图片验证码2、创建验证码过滤器3、将过滤器加入SpringSecurity过滤链4、修改登录页 SpringSecurity是通过过滤器链来完成的,接下来的验证码,可以尝试创建一个过滤器放到Security的过滤器链中,在自定义的过滤器中比较验证码。…...

【本地代码问题】启动程序,报错:java.lang.IllegalArgumentException: No selectors
启动程序的时候报错了 问题怎么出现的解决方式,注释掉jetty的内容,回归tomcat的使用 问题怎么出现的 我本地启动程序的时候报错了:报的是这个错误,可能和容器的选择有关吧 解决方式,注释掉jetty的内容,回…...

手写RPC框架--4.服务注册
RPC框架-Gitee代码(麻烦点个Starred, 支持一下吧) RPC框架-GitHub代码(麻烦点个Starred, 支持一下吧) 服务注册 服务注册a.添加服务节点和主机节点b.抽象注册中心c.本地服务列表 服务注册 a.添加服务节点和主机节点 主要完成服务注册和发现的功能,其具体流程如下&…...

oracle 解锁表
操作的前提 用 sys 用户 以 SYSDBA 角色登录 第一种解锁方式 1.查询被锁的表 select object_name,machine,s.sid,s.serial# from v$locked_object l,dba_objects o ,v$session s where l.object_id o.object_id and l.session_ids.sid;2.查询那个session引起表被锁 sele…...

使用Dbeaver连接GaussDB
1.下载DBeaver,官网地址 2.安装软件,打开软件,点击数据库->驱动管理器,具体操作如下图: 3、选择新建后进行参数设置,如下图: 具体参数如下图 驱动名称: GS #随便定义 驱动类型&#…...

WSL使用技巧 / 虚拟机对比
WSL使用技巧 / 虚拟机对比 前言虚拟机比较VMware使用技巧WSL使用技巧官方文档工具安装WSL基本命令运行命令关闭卸载磁盘管理导入导出指定安装路径 前言 本文介绍了VMware和WSL的区别,并详细介绍了WSL的使用方法和技巧。 虚拟机比较 VMware 比较灵活,拥…...

vuex_cart案例
json-server使用 在目录下新建db文件夹>里面新建index.json index.json {"cart": [{"id": 100001,"name": "低帮城市休闲户外鞋天然牛皮COOLMAX纤维","price": 128,"count": 6,"thumb": "http…...

Linux系统的安装
文章目录 1 Linux介绍1.1 Linux是什么1.2 Linux的特点1.3 Linux的应用1.4 Linux的发行版本1.5 Linux的Shell 2 Linux安装2.1 安装方式2.2 什么是VMware2.3 VMware主要功能2.4 什么是CentOS2.5 VMware与CentOS与Linux的关系2.6 VMware安装CentOS的步骤 1 Linux介绍 1.1 Linux是…...

微服务设计和高并发实践
文章目录 1、微服务的设计原则1.1、服务拆分方法1.2、微服务的设计原则1.3、微服务架构 2、高并发系统的一些优化经验2.1、提高性能2.1.1、数据库优化2.1.2、使用缓存2.1.3、服务调用优化2.1.4、动静分离2.1.5、数据库读写分离 2.2、服务高可用2.2.1、限流和服务降级2.2.2、隔离…...

2023年高教社杯数学建模思路 - 案例:粒子群算法
文章目录 1 什么是粒子群算法?2 举个例子3 还是一个例子算法流程算法实现建模资料 # 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 什么是粒子群算法? 粒子群算法(Pa…...

Tomcat 集群介绍
一.Tomcat 集群介绍 在实际生产环境中,单台 Tomcat 服务器的负载能力或者说并发能力在四五百左右。大 部分情况下随着业务增长,访问量的增加(并发量不止四五百),单台 Tomcat 服务器是 无法承受的。这时就需要将多台 Tomcat 服务器组织起来&a…...

Windows右键添加用 IDEA 打开
1.安装IDEA时 安装时会有个选项来添加,如下: 勾选即可 2.修改注册表 安装时未勾选,可以把下面代码中程序路径改为自己的,保存为对应的 idea.reg文件,双击即可 Windows Registry Editor Version 5.00[HKEY_CLASSES…...

Golang 中return和defer执行先后顺序
先给出最终结论: 执行return语句 -> 执行defer函数 -> 函数返回 这里可能会有一个疑问, 执行return语句和函数返回难道不是一回事? Golang语言中函数的return不是原子操作,而是分为了两步: 返回值赋值真正函数返回 Gol…...

业务数据模拟/采集
业务数据模拟/采集 2.2 业务数据模拟 2.2.1 连接MySQL 通过MySQL可视化客户端连接数据库。2.2.2 建表语句 1)通过SQLyog创建数据库2)设置数据库名称为gmall,编码为utf-8,排序规则为utf8_general_ci3)导入数据库结构脚本…...

qt day 5
实现局域网的网络聊天室功能 1>服务器代码 --------------------------------------------------------------- widget.h --------------------------------------------------------------- #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMes…...

Java设计模式之适配器模式
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。 这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子࿰…...

每天一个工业通信协议(3)2023.8.29 (DAP接口)
文章目录 参考文献1.DAP接口介绍2.DAP接口的2/3pin3.一种DAP接口方案应用的说明,通过两步初始化把JTAG接口变成DAP接口使用4.DAP接口的协议4.1 DAP电报的分类(只用JTAG类电报)4.2 电报格式4.3 DAP有限状态机参考文献 李婧. DAP模块验证组件系统级开发和实现[D]. 陕西:西安电…...

如何将Word转成PDF?试一下这个转换方法
Word转成PDF是现代办公中常见的需求,它可以确保文件的格式和内容在不同平台上保持一致,并且更加方便共享和打印。在这个数字化时代,我们经常需要将Word文档转换为PDF格式,无论是个人用户还是商务用户都会遇到这样的需求。那么如何…...