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

文章目录

  • 一:模板方法设计模式概述
    • 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. 钩子方法的命名应该具有描述性,以便子类理解和正确使用。

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

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

相关文章

爬虫--爬取自己想去的目的的车票信息

前言: 本篇文章主要作为一个爬虫项目的小练习,来给大家进行一下爬虫的大致分析过程以及来帮助大家在以后的爬虫编写中有一个更加清晰的认识。 一:环境配置 Python版本:3.7 IDE:PyCharm 所需库:requests&#xff0…

Mysql数据库事务隔离级别造成死锁

场景:如下代码,获取数据库连接,删除权限的时候,会造成数据库死锁. 代码 日志: 数据库: SHOW OPEN TABLES where In_use > 0; 问题分析:测试环境Centos7操作系统,Mysql5.7.40版本程序运行正常,开发环境Windows操…

O2OA(翱途)开发平台 V8.1正式发布

尊敬的O2OA(翱途)平台合作伙伴、用户以及亲爱的开发小伙伴们,平台 V8.1版本已正式发布。正值8月的最后一周,我们以更安全、更高效、更好用的崭新面貌迎接9月的到来。 O2OA开发平台v8.1版本更注重于对系统级别的安全防护。其中重大的更新,是对…

ELK安装、部署、调试(四)KAFKA消息队列的安装和部署

1.简介 Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通…

Nginx 部署 配置

一.概述 什么是nginx? Nginx (engine x) 是一款轻量级的Web 服务器 、反向代理服务器及电子邮件(IMAP/POP3)代理服务器。 什么是反向代理? 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求…

【代码随想录day23】不同路径

题目 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径? 示…

Mysql高级语句

高级语句 1.按关键字排序 SELECT column1, column2, ... FROM table_name ORDER BY column1, column2, ... ASC|DESC ASC 是按照升序进行排序的,是默认的排序方式,即 ASC 可以省略。 SELECT 语句中如果没有指定具体的排序方式,则默认按 ASC…

AP51656 PWM和线性调光 LED车灯电源驱动IC 兼容替代PT4115 PT4205

产品描述 AP51656是一款连续电感电流导通模式的降压恒流源 用于驱动一颗或多颗串联LED 输入电压范围从 5V 到 60V,输出电流 可达 1.5A 。根据不同的输入电压和 外部器件, 可以驱动高达数十瓦的 LED。 内置功率开关,采用高端电流采样设置 …

Ubuntu入门05——磁盘管理与备份压缩

1.检查磁盘空间占用情况 2.统计目录或文件所占磁盘空间大小 3.压缩 3.1 zip、unzip和zipinfo 运行时发现上面命令不成功,换成: (将文件lkw放入压缩文件lkw01.zip中) sudo zip -m lkw01.zip lkw 解压文件: 实操&…

css学习7(盒子模型)

1、盒子模型图&#xff1a; Margin(外边距) - 清除边框外的区域&#xff0c;外边距是透明的。Border(边框) - 围绕在内边距和内容外的边框。Padding(内边距) - 清除内容周围的区域&#xff0c;内边距是透明的。Content(内容) - 盒子的内容&#xff0c;显示文本和图像。 <!DO…

Vue框架--Vue中的数据代理

下面,我们一起来说以下Vue中的数据代理。 1.Object.defineProperty()方法回顾 * Object.defineProperty()方法基本配置项 * value:指定设置对象内容的属性值 * enumerable:true, //控制属性是否可以枚举(也就是是否可以被遍历),默认值是false * writable:true, //控制属性是…

three.js(四):react + three.js

绘制多个立方体 1.搭建reactts 项目 npx create-react-app basics-demo --template typescriptreactts 的用法可参考此链接&#xff1a; https://react-typescript-cheatsheet.netlify.app/docs/basic/setup 2.安装three依赖 npm install three types/three --save3.安装路…

Anaconda Prompt输入jupyter lab无反应

问题&#xff1a;Anaconda Prompt界面输入指令无反应 原因&#xff1a;公司电脑勒索病毒防御工具阻止了进程 解决&#xff1a;找到黑名单恢复进程

Android 1.2 开发环境搭建

目录 1.2 开发环境搭建 1.JDK安装与配置 2.开发工具二选一 3.相关术语的解析 4.ADB命令行的一些指令 5.APP程序打包与安装的流程&#xff1a; 6.APP的安装过程&#xff1a; 7.本节小结 1.2 开发环境搭建 现在主流的Android开发环境有: ①Eclipse ADT SDK ②Android Stu…

Kafka3.0.0版本——手动调整分区副本示例

目录 一、服务器信息二、启动zookeeper和kafka集群2.1、先启动zookeeper集群2.2、再启动kafka集群 三、手动调整分区副本3.1、手动调整分区副本的前提条件3.2、手动调整分区副本的示例需求3.3、手动调整分区副本的示例 一、服务器信息 四台服务器 原始服务器名称原始服务器ip节…

【算法与数据结构】617、LeetCode合并二叉树

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;采用递归的方式遍历二叉树&#xff0c;【算法与数据结构】144、94、145LeetCode二叉树的前中后遍历&am…

Debian12搭建Nextcloud最新版并frp到二级域名

起因&#xff1a;因为台风的原因&#xff0c;要居家办公&#xff0c;但正值公司业务最要紧的时刻&#xff0c;所以需要搭建远程共享&#xff0c;结果发现基于原有的经验&#xff0c;已经难以适应版本更新带来的问题&#xff0c;所以就解决方法&#xff0c;进行了一次重新总结&a…

Ubuntu 20.04 Server配置网络

0&#xff0c;环境 服务器&#xff1a; Intel(R) Xeon(R) Gold 6248R CPU 3.00GHz 96核 网卡&#xff1a; 多网卡 1&#xff0c; 镜像下载 http://old-releases.ubuntu.com/releases/ubuntu-20.04.1-desktop-amd64.iso 2&#xff0c; 系统安装--具体步骤就不贴出来&#…

CentOs下面安装jenkins记录

目录 一、安装jenkins 二、进入jenkins 三、安装和Gitee&#xff0c;Maven , Publish Over SSH等插件 四、构建一个maven项目 一、安装jenkins 1 wget -O /etc/yum.repos.d/jenkins.repo \ https://pkg.jenkins.io/redhat-stable/jenkins.repo 2 rpm --im…

美创科技获通信网络安全服务能力评定(应急响应一级)认证!

近日&#xff0c;中国通信企业协会公布通信网络安全服务能力评定2023年第一批获证企业名单。 美创科技获得应急响应一级资质&#xff0c;成为2023年第一批获证企业之一&#xff01; 通信网络安全服务能力评定是对通信网络安全服务单位从事通信网络安全服务综合能力的评定&#…