重温设计模式--模板方法模式

news2025/2/25 15:17:36

文章目录

  • 一、模板方法模式概述
  • 二、模板方法模式UML图
  • 三、优点
    • 1代码复用性高
    • 2可维护性好
    • 3扩展性强
  • 四、缺点
  • 五、使用场景
  • 六、C++ 代码示例1
  • 七、 C++ 代码示例2

一、模板方法模式概述

定义:定义一个操作中的算法骨架,而降一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
定义:模板方法模式是一种行为设计模式。它在一个抽象类中定义了一个算法的骨架(模板方法),将一些步骤的实现延迟到子类中。模板方法定义了算法的步骤顺序,子类可以根据自身的需求重写其中的某些步骤,而整体算法的流程结构保持不变。

二、模板方法模式UML图

在这里插入图片描述

三、优点

1代码复用性高

在抽象类中定义的模板方法和一些通用步骤可以在多个子类中复用,避免了代码的重复编写。例如,在一个游戏开发中,游戏角色的移动和攻击行为可能有共同的流程结构,通过模板方法模式可以把这个共同的流程提取出来,不同类型的角色(如战士、法师)可以复用这个流程,只需要实现自己特定的移动和攻击方式即可。

2可维护性好

由于算法的结构在抽象类中已经定义好,当需要对整体算法流程进行修改时,只需要在抽象类中修改模板方法的实现,而不需要在每个具体子类中进行修改。比如,在一个文件读取处理的系统中,如果要改变文件读取后的处理流程顺序,只需要在抽象的文件处理类的模板方法中调整步骤顺序,而各个具体文件类型(如文本文件、二进制文件)的处理子类可以保持不变。

3扩展性强

可以很方便地通过创建新的子类来扩展系统功能。新的子类可以选择性地重写模板方法中的步骤,以实现新的行为。例如,在一个图形绘制系统中,已经有了绘制基本图形(如圆形、矩形)的类,当需要添加一种新的图形(如三角形)时,只需要创建一个新的子类,重写绘制图形的具体步骤,而整体的图形绘制流程(如打开画布、选择颜色、绘制图形、关闭画布)可以复用已有的模板方法。

四、缺点

可能会导致类的层次结构复杂:因为需要创建抽象类和多个子类来实现模板方法模式,所以如果设计不当,可能会导致类的层次结构过于复杂,增加代码的理解和维护难度。
不符合开闭原则的部分情况:虽然模板方法模式在一定程度上符合开闭原则(对扩展开放,对修改关闭),但如果要对模板方法本身进行修改,可能会影响到所有的子类。例如,在模板方法中增加或删除一个步骤,可能需要在所有子类中进行相应的调整。

五、使用场景

多个子类有共同的算法流程,但某些步骤的实现细节不同:比如在一个订单处理系统中,线上订单和线下订单的处理流程都包括接收订单、处理支付、安排发货等步骤,但线上订单和线下订单在处理支付和安排发货的具体方式上可能不同。
需要控制子类的扩展行为,保证算法结构的稳定性:例如在一个编译器的语法分析模块中,不同编程语言的语法分析都有一个基本的流程,如词法分析、语法树构建、语义检查等步骤。通过模板方法模式可以定义这个基本流程,让不同编程语言的语法分析子类在这个框架内进行扩展,同时保证整体的语法分析算法结构不变。

六、C++ 代码示例1

以下是一个简单的 C++ 代码示例,模拟一个游戏角色攻击的模板方法模式。假设有一个抽象的 GameCharacter 类,定义了游戏角色攻击的模板方法,还有两个具体的角色类 Warrior 和 Mage,它们分别重写了攻击的具体实现方式。

#include <iostream>
#include <string>

// 抽象游戏角色类
class GameCharacter 
{
public:
	// 模板方法,定义了攻击的算法流程
	void attack()
	{
		std::cout << "The character is preparing to attack." << std::endl;
		performAttack();
		std::cout << "The character has finished the attack." << std::endl;
	}
protected:
	// 抽象方法,由子类实现具体的攻击方式
	virtual void performAttack() = 0;
};

// 战士角色类
class Warrior : public GameCharacter
{
protected:
	void performAttack() override 
	{
		std::cout << "1" << std::endl;
		std::cout << "2" << std::endl;
		std::cout << "The warrior swings his sword." << std::endl;
	}
};

// 法师角色类
class Mage : public GameCharacter
{
protected:
	void performAttack() override 
	{
		std::cout << "The mage casts a spell." << std::endl;
		std::cout << "888" << std::endl;
		std::cout << "777" << std::endl;
	}
};
int main() 
{
	Warrior warrior;
	Mage mage;
	std::cout << "Warrior's attack:" << std::endl;
	warrior.attack();
	std::cout << "Mage's attack:" << std::endl;
	mage.attack();
	char t;
	std::cin>>t;
	return 0;
}

在上述代码中:
首先定义了抽象类 GameCharacter,它有一个公共的方法 attack,这就是模板方法。在 attack 方法中,定义了攻击行为的算法流程,包括准备攻击、执行具体的攻击动作(通过调用纯虚函数 performAttack)和完成攻击。performAttack 函数是一个纯虚函数,需要在子类中实现。
然后定义了两个具体的子类 Warrior 和 Mage,它们都继承自 GameCharacter。在这两个子类中,分别重写了 performAttack 函数,实现了战士挥舞剑和法师释放法术的不同攻击方式。
在 main 函数中,创建了 Warrior 和 Mage 类型的对象,并分别调用它们的 attack 方法,这样就会按照模板方法中定义的流程执行攻击行为,每个角色会执行自己特有的攻击动作。

七、 C++ 代码示例2

#include<iostream>
using namespace std;

//抽象类,
//在父类中定义操作的算法骨架,而具体的实现由子类完成
class resume
{
protected:
	virtual void setedu(){}
	virtual void setage(){}
	virtual void setexp(){}
public:
	void setinformation()//骨架
	{
		setedu();
		setage();
		setexp();
	}
};
//子类
class xiaoming:public resume
{
	void setedu(){cout<<"清华大学"<<endl;}//具体实现
	void setage(){cout<<"19岁"<<endl;}//具体实现
};
class xiaoli:public resume
{
	void setedu(){cout<<"北京大学"<<endl;}//具体实现
	void setage(){cout<<"10岁"<<endl;}//具体实现
	void setexp(){cout<<"腾讯科技"<<endl;}
};
int main()
{
	resume *s1 = new xiaoming();
	s1->setinformation();
	cout<<endl<<endl;
	resume *s2 = new xiaoli();
	s2->setinformation();
	char t;
	std::cin>>t;
	return 0;
}

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

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

相关文章

@vue/cli启动异常:ENOENT: no such file or directory, scandir

参考:https://blog.csdn.net/qq_44355188/article/details/122239566 首先异常报错是&#xff1a;ENOENT: no such file or directory, scandir ‘D:\Data\Project\VueProject\hello\node_modulesvue\cli-plugin-eslint\locales’&#xff1b;我的vue/cli版本是 4.5.15 重点是…

Jenkins集成部署(图文教程、超级详细)

一、CI/CD 的概念 ​ CI/CD一般包含三个概念&#xff1a; 持续集成&#xff08;Continuous Integration &#xff0c;CI&#xff09; 持续交付&#xff08;Continuous Delivery&#xff09; 持续部署&#xff08;Continuous Deploy&#xff09; ​ CI/CD 是现代软件开发的重要…

2.在 Vue 3 中使用 ECharts 实现动态时间轴效果

在前端开发中&#xff0c;时间轴&#xff08;Timeline&#xff09;是一种常见且有效的方式来展示时间相关的数据。在本篇文章中&#xff0c;我们将展示如何在 Vue 3 项目中使用 ECharts 创建一个具有动态时间范围的时间轴&#xff0c;并添加了今日时间的标记以及通过按钮来前进…

【EthIf-13】EthIfGeneral容器配置-01

1.EthIfGeneral类图结构 下面是EthIfGeneral配置参数的类图&#xff0c;比较重要的参数就是配置&#xff1a; 接收中断是否打开发送确认中断是否打开EthIf轮询周期 1.EthIfGeneral参数的含义

卓软计量业务管理平台 image.ashx 任意文件读取漏洞复现

0x01 产品简介 卓软计量业务管理平台是一款专为计量测试检定机构设计的信息化管理系统。随着社会经济的不断发展,计量测试检定机构面临的管理规范化、技术水平、检测效率、服务能力以及行业竞争等问题日益增多。卓软计量业务管理平台旨在通过信息化手段,帮助机构实现业务管理…

BCSP-X 2024 Scratch图形化编程 小学低年级组 真题

BCSP-X 2024-2 图形化编程 小学低年级组 真题 题目总数&#xff1a;40 总分数&#xff1a;100 选择题 第 1 题 单选题 在下面各世界顶级的奖项中&#xff0c;为计算机科学与技术领域做出杰出贡献的科学 家设立的奖项是?( ) A. 奥斯卡奖 B. 诺贝尔奖 C. 菲尔兹…

GCP GCA认证考试Case错题库1(JenciMart+Helicopter+EHR)

GCP GCA认证考试Case错题库1(JenciMartHelicopterEHR) 整理by Moshow郑锴https://zhengkai.blog.csdn.net/ JenciMart 在生产和开发资源之间进行管理职责分离的最小权限模型中&#xff0c;最佳实践是每个应用程序的每个阶段都有自己的项目。这种设置确保权限是细化的&#xf…

centos权限大集合,覆盖多种权限类型,解惑权限后有“. + t s”问题!

在 CentOS 系统中&#xff0c;权限管理是操作系统的核心功能之一&#xff0c;确保不同用户和进程对文件、目录以及设备的访问被合理控制。 权限系统主要包括传统的 Unix 权限模型、特殊权限&#xff08;SetUID、SetGID、Sticky 位&#xff09;和更精细的访问控制列表&#xff…

HarmonyOS NEXT 技术实践-基于基础视觉服务实现骨骼点识别

本示例展示了如何在HarmonyOS Next中实现基于基础视觉服务的骨骼点识别功能。骨骼点识别是计算机视觉中的一项重要技术&#xff0c;广泛应用于运动分析、健身监控和增强现实等领域。通过使用HarmonyOS Next提供的视觉API&#xff0c;开发者能够轻松地对人物图像进行骨骼点检测&…

【RAG实战】语言模型基础

语言模型赋予了计算机理解和生成人类语言的能力。它结合了统计学原理和深度神经网络技术&#xff0c;通过对大量的样本数据进行复杂的概率分布分析来学习语言结构的内在模式和相关性。具体地&#xff0c;语言模型可根据上下文中已出现的词序列&#xff0c;使用概率推断来预测接…

workman服务端开发模式-应用开发-vue-element-admin挂载websocket

一、项目根目录main.js添加全局引入 import /utils/websocket 二、在根目录app.vue 中初始化WebSocket连接 <template><div id"app"><router-view /></div> </template><script>import store from ./store export default {n…

2024-12-24 NO1. XR Interaction ToolKit 环境配置

文章目录 1 软件配置2 安装 XRToolKit3 配置 OpenXR4 安装示例场景5 运行测试 1 软件配置 Unity 版本&#xff1a;Unity6000.0.26 ​ 2 安装 XRToolKit 创建新项目&#xff08;URP 3D&#xff09;&#xff0c;点击进入 Asset Store。 进入“Unity Registry”页签&#xff0…

华为手机鸿蒙4.2连接不上adb

1、下载HiSuite华为手机助手 https://consumer.huawei.com/cn/support/hisuite/ 2、安装后点连接 3、就可以adb连接了

GitPuk安装配置指南

GitPuk是一款开源免费的代码管理工具&#xff0c;上篇文章已经介绍了Gitpuk的功能与优势&#xff0c;这篇文章将为大家讲解如何快速安装和配置GitPuk&#xff0c;助力你快速的启动GitPuk管理代码 1. 安装 支持 Windows、Mac、Linux、docker 等操作系统。 1.1 Windows安装 下载…

【从零开始入门unity游戏开发之——C#篇20】C#面向对象的封装——静态成员(`static`)(静态字段、静态方法、静态属性、静态构造函数、静态类)

文章目录 静态成员&#xff08;static&#xff09;1、静态成员的特点&#xff1a;2、为什么可以直接点出来使用&#xff1f;3、不同的静态成员介绍3.1. 静态字段3.2. 静态方法3.3. 静态属性3.4. 静态构造函数3.5. 静态类 4、静态成员的优缺点优点&#xff1a;缺点&#xff1a; …

【Yonghong 企业日常问题 06】上传的文件不在白名单,修改allow.jar.digest属性添加允许上传的文件SH256值?

文章目录 前言问题描述问题分析问题解决1.允许所有用户上传驱动文件2.如果是想只上传白名单的驱动 前言 该方法适合永洪BI系列产品&#xff0c;包括不限于vividime desktop&#xff0c;vividime z-suit&#xff0c;vividime x-suit产品。 问题描述 当我们连接数据源的时候&a…

我的JAVA-Web基础(2)

1.JDBC 防止sql注入 2.JSP JSP的基本语法 基本语法是 <% %> Java代码 <% %> 输出变量 可以转换成${变量}的EL表达式 <%! %>定义变量 JSP的基本语法包括以下几个主要部分&#xff1a; 1. 表达式&#xff08;Expression&#xff09; 表达式用于将…

新闻网站的个性化推荐:机器学习的应用

3.1可行性分析 开发者在进行开发系统之前&#xff0c;都需要进行可行性分析&#xff0c;保证该系统能够被成功开发出来。 3.1.1技术可行性 开发该新闻网站所采用的技术是vue和MYSQL数据库。计算机专业的学生在学校期间已经比较系统的学习了很多编程方面的知识&#xff0c;同时也…

IIC驱动EEPROM

代码参考正点原子 i2c_dri:主要是三段式状态机的编写 module iic_dri#(parameter SLAVE_ADDR 7b1010000 , //EEPROM从机地址parameter CLK_FREQ 26d50_000_000, //模块输入的时钟频率parameter I2C_FREQ 18d250_000 //IIC_SCL的时钟频率)( …

【动手学轨迹预测】2.3 场景表征方法

场景表征是指在所有可用的场景信息数据中, 提取出对于预测网络有用的数据, 并将其转换为易于模型学习的数据格式. 对于预测网络来说, 最重要的数据是交通参与者的历史轨迹和地图信息, 表达它们的常见方法有:栅格化和稀疏化 2.1.1 栅格化 多通道表达 如上图所示, 将历史轨迹和…