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

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

文章目录

  • 一:模板方法设计模式概述
    • 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() 方法是模板方法,控制了角色的创建流程。具体的角色类 WarriorCharacterMageCharacter 继承了 Character 并实现了其中的抽象方法 doSomething(),完成了自己特定的行为。最后,在 Main 类中测试了这两个具体的角色类的创建过程。

通过运行上述代码示例,你可以看到不同角色的创建流程遵循了模板方法定义的骨架,但同时具体的角色类可以根据自身的需求实现不同的行为和技能。这就是模板方法设计模式的应用。

五:模板方法设计模式应用注意事项

5.1 钩子方法的使用场景和注意事项

钩子方法是在模板方法设计模式中的一种特殊方法,它在抽象类中提供了一个默认的空实现,子类可以选择性地覆盖或扩展这个方法。钩子方法的主要作用是允许子类在模板方法的特定点插入自己的逻辑,以实现对算法的定制和扩展。

使用钩子方法可以使得模板方法更加灵活和可扩展,同时也可以避免在抽象类中定义过多的抽象方法,简化了子类的实现。

一般来说,钩子方法的使用场景包括但不限于以下几种情况:

  1. 选择性执行:某些步骤在特定条件下需要执行,而在其他条件下可以跳过,钩子方法可以判断这些条件并决定是否执行相应步骤。
  2. 扩展功能:在模板方法的特定点添加新的逻辑或功能,用于满足不同的需求。
  3. 改变顺序:通过覆盖或扩展钩子方法,改变模板方法中步骤的执行顺序。

在使用钩子方法时,需要注意以下几点:

  1. 钩子方法的命名:钩子方法应该具有描述性的、能够体现其作用的命名,以便子类理解和正确使用。
  2. 钩子方法的默认实现:钩子方法在抽象类中应该有一个默认的空实现,以保证子类可以选择是否覆盖它。
  3. 钩子方法的调用时机:钩子方法应该在适当的时机被调用,以确保它们的逻辑能够正确地插入到模板方法中。

5.2 与其他设计模式的关系

模板方法设计模式与其他设计模式之间存在一些关系和区别。下面是一些常见的与模板方法设计模式相关的设计模式:

  1. 工厂方法模式(Factory Method Pattern):工厂方法模式也是一种创建型设计模式,它将对象的创建延迟到子类中进行。在工厂方法模式中,模板方法用于定义对象的创建过程,具体的产品由子类来实现。可以说,工厂方法模式是模板方法设计模式在创建对象方面的一种应用。
  2. 策略模式(Strategy Pattern):策略模式用于封装一系列的算法,并使它们可以互相替换。在策略模式中,每个算法都是一个独立的类,而模板方法则是在抽象类中定义的一系列步骤。可以说,策略模式是模板方法设计模式在算法封装方面的一种应用。

需要注意的是,模板方法设计模式和以上提到的设计模式并不是相互排斥的关系,它们可以结合使用来解决复杂的问题。在实际开发中,根据具体的需求和场景选择合适的设计模式,能够更好地设计和实现高质量的代码。

5.3 使用建议和最佳实践

以下是一些使用模板方法设计模式的建议和最佳实践:

  1. 合理划分抽象类和具体类:抽象类应该包含公共的行为和模板方法,具体类应该实现自己特定的行为。
  2. 提取公共的方法和逻辑:将公共的方法和逻辑提取到抽象类中,以避免代码的重复和冗余。
  3. 明确模板方法的执行流程:定义好模板方法的执行顺序,并确保每个步骤的执行时机正确。
  4. 合理使用钩子方法:在需要灵活定制或扩展的地方使用钩子方法,但不要滥用。过多的钩子方法可能导致代码难以理解和维护。
  5. 考虑模板方法的可变性:模板方法应该具有一定的可变性,以便子类可以根据自身需要进行定制。但同时也要保持模板方法的稳定性和一致性。

结语

模板方法设计模式是一种行为设计模式,它通过定义一个算法的骨架,在抽象类中封装了算法的主要步骤,并使用抽象方法和钩子方法来实现可变的部分。这种设计模式使得算法的结构保持稳定,而具体的实现细节可以由子类提供。

模板方法设计模式的优势在于:

  1. 提高代码复用性:将共同的代码逻辑封装在抽象类中,可以在不同的子类中共享使用,避免了重复编写相似的代码。
  2. 简化子类实现:通过将算法中的可变部分定义为抽象方法,子类只需要关注自己特定的实现细节,从而简化了子类的实现。
  3. 提供扩展点:通过钩子方法,允许子类在特定的执行点插入自己的逻辑,以实现对算法的定制和扩展。

然而,在使用模板方法设计模式时也需要考虑一些因素和注意事项:

  1. 需要明确模板方法的执行流程和步骤顺序,确保每个步骤的执行时机正确。
  2. 钩子方法应该有默认的空实现,以保证子类可以选择是否覆盖它。
  3. 合理使用钩子方法,不要过度使用,避免引入不必要的复杂性。
  4. 钩子方法的命名应该具有描述性,以便子类理解和正确使用。

相关文章:

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

文章目录 一:模板方法设计模式概述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&#xff0…...

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是…...

One API 部署教程(下):使用指南

导读:前面两篇讲了本地和线上部署,现在 One API 已经跑起来了,接下来就是真正的使用环节! 理解核心概念 在开始之前,咱们先搞清楚几个关键概念,不然后面容易晕。 渠道(Channel):就是你的各个 AI 平台的 API Key。比如你有 DeepSeek 的 Key、OpenAI 的 Key、通义千问…...

如何快速获取免费的EB Garamond 12字体:古典优雅的终极排版解决方案

如何快速获取免费的EB Garamond 12字体:古典优雅的终极排版解决方案 【免费下载链接】EBGaramond12 项目地址: https://gitcode.com/gh_mirrors/eb/EBGaramond12 EB Garamond 12是一款完全免费的开源字体,完美复刻了16世纪Claude Garamont的经典…...

3个高效方法解决抖音素材管理难题:从零散文件到有序素材库

3个高效方法解决抖音素材管理难题:从零散文件到有序素材库 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback s…...

2026届最火的六大AI辅助论文网站实际效果

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 人工智能技术飞速发展着,智能内容生成也就是AIGC,正一步步渗透到学术…...

ARM中断机制深度解析:从硬件原理到实战调试与RTOS应用

1. 项目概述:从一行代码到硬件响应“ARM体系架构处理器的中断程序分析”这个标题,对于很多嵌入式开发者和系统软件工程师来说,就像一把钥匙。它指向了连接软件逻辑与硬件实时响应的核心枢纽。我处理过太多因为中断没玩明白而导致的系统“玄学…...

UVM验证中的迭代模式:从寄存器遍历到配置组合的实战应用

1. 项目概述:为什么要在UVM中谈迭代模式?如果你做过芯片验证,尤其是用SystemVerilog和UVM搭过测试平台,那你肯定对“遍历”这个概念不陌生。比如,你需要检查一个存储阵列里每一个地址的读写是否正确,或者需…...

电力线路保护原理与整定计算实战解析:从电流、距离到差动保护

1. 项目概述:从“黑匣子”到“透明逻辑”在电力系统这个庞大而精密的网络中,输电线路如同人体的动脉血管,承担着输送能量的核心使命。然而,这条“动脉”时刻面临着雷击、外力破坏、绝缘老化、过负荷等各类风险的威胁。一旦发生故障…...

IDEA里Git冲突别慌!手把手教你用Rebase和Merge搞定,附代码消失急救指南

IDEA中Git冲突与代码消失的终极解决方案:Rebase与Merge实战指南 在团队协作开发中,Git冲突如同程序员日常的"必修课",而IDEA作为Java开发者最信赖的IDE,其内置的Git工具链却常被低估。当你在深夜赶进度时突然遭遇冲突警…...

5步实现Windows电脑直接运行安卓应用:APK安装器终极指南

5步实现Windows电脑直接运行安卓应用:APK安装器终极指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer APK安装器是一款革命性的Windows工具,让…...

从LVGL官方例程到自定义界面:在Windows上用CodeBlocks模拟器快速玩转GUI设计

从LVGL官方例程到自定义界面:在Windows上用CodeBlocks模拟器快速玩转GUI设计 对于嵌入式开发者而言,图形用户界面(GUI)设计往往需要在硬件平台上反复烧录测试,效率低下。而LVGL模拟器配合CodeBlocks的组合,为开发者提供了一个在PC…...