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

文章目录

  • 一、模板方法模式概述
  • 二、模板方法模式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.rhkb.cn/news/493069.html

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

相关文章

林子雨-大数据课程实验报告(一)

实验一&#xff1a;熟悉常用的Linux操作和Hadoop操作 一、实验目的 Hadoop运行在Linux系统上&#xff0c;因此&#xff0c;需要学习实践一些常用的Linux命令。本实验旨在熟悉常用的Linux操作和Hadoop操作&#xff0c;为顺利开展后续其他实验奠定基础。 二、实验平台 操作系统…

时间序列异常值检测方法

文章目录 一、基于统计的方法1.1、标准差1.2、箱线图1.3、Z-Score法 二、基于机器学习算法的方法2.1、K-NN2.2、孤立森林 三、基于密度的方法3.1、LOF3.2、DBSCAN密度聚类 时间序列相关参考文章&#xff1a; 时间序列预测算法—ARIMA 时间序列预测算法—Prophet 时间序列分类任…

#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

Moretl开箱即用日志采集

永久免费: 至Gitee下载 使用教程: Moretl使用说明 使用咨询: 用途 定时全量或增量采集工控机,电脑文件或日志. 优势 开箱即用: 解压直接运行.不需额外下载.管理设备: 后台统一管理客户端.无人值守: 客户端自启动,自更新.稳定安全: 架构简单,兼容性好,通过授权控制访问. 架…

Go框架比较:goframe、beego、iris和gin

由于工作需要&#xff0c;这些年来也接触了不少的开发框架&#xff0c;Golang的开发框架比较多&#xff0c;不过基本都是Web"框架"为主。这里稍微打了个引号&#xff0c;因为大部分"框架"从设计和功能定位上来讲&#xff0c;充其量都只能算是一个组件&…

DB-GPT 智谱在线模型配置

LLM_MODELzhipu_proxyllm PROXY_SERVER_URLhttps://open.bigmodel.cn/api/paas/v4/chat/completions ZHIPU_MODEL_VERSIONglm-4 ZHIPU_PROXY_API_KEY70e8ec7113882ff5478fcecaa47522479.ExY2LyjcvWmqrTAf

【GCC】2015: draft-alvestrand-rmcat-congestion-03 机器翻译

腾讯云的一个分析,明显是看了这个论文和草案的 : 最新的是应该是这个 A Google Congestion Control Algorithm for Real-Time Communication draft-ietf-rmcat-gcc-02 下面的这个应该过期了: draft-alvestrand-rmcat-congestion-03

python:用 sklearn 构建线性回归模型,并评价

编写 test_sklearn_6.py 如下 # -*- coding: utf-8 -*- """ 使用 sklearn 估计器构建线性回归模型 """ import numpy as np import pandas as pd import matplotlib.pyplot as plt from matplotlib import rcParamsfrom sklearn import dataset…

系统思考—战略共识

当企业不增长的时候&#xff0c;是忙着救火&#xff0c;还是在真正解决问题&#xff1f; 最近遇到很多领导者&#xff0c;把精力放在“管理”上&#xff0c;希望通过抓细节提升效率&#xff0c;解决经营问题。结果呢&#xff1f;全公司上上下下忙成了一团乱麻&#xff0c;但不…

web3跨链桥协议-Nomad

项目介绍 Nomad是一个乐观跨链互操作协议。通过Nomad协议&#xff0c;Dapp能够在不同区块链间发送数据&#xff08;包括rollups&#xff09;&#xff0c;Dapp通过Nomad的合约和链下的代理对跨链数据、消息进行验证、传输。其安全通过乐观验证机制和欺诈证明制约验证者实现&…

微信小程序实现画板画布自由绘制、选择画笔粗细及颜色、记录撤回、画板板擦、清空、写字板、导出绘图、canvas,开箱即用

目录 画板创建canvas绘制及渲染画笔粗细功能实现画笔颜色选择画笔痕迹撤回、板擦、画布清空canvas解析微信小程序中 canvas 的应用场景canvas 与 2D 上下文、webgl 上下文的关系图像的加载与绘制说明代码说明画板创建 canvas绘制及渲染 在wxml添加对应的canvas标签代码,并在j…

网站灰度发布?Tomcat的8005、8009、8080三个端口的作用什么是CDNLVS、Nginx和Haproxy的优缺点服务器无法开机时

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把…

解锁BL后的K40降级

1 下载刷机工具 https://miuiver.com/miflash/ 2、下载刷机包 https://xiaomirom.com/series/ 下载ROM包&#xff0c;12.0.8比较好 3 打开第一步下载的刷机工具 打开首次安装驱动&#xff0c; 接下来先选择个重要的东西&#xff0c;如果不想重新上BL那就选择全部删除…

蓝桥杯刷题——day8

蓝桥杯刷题——day8 题目一题干解题思路代码 题目二题干解题思路代码 题目一 题干 N 架飞机准备降落到某个只有一条跑道的机场。其中第i架飞机在 Ti时刻到达机场上空&#xff0c;到达时它的剩余油料还可以继续盘旋 Di个单位时间&#xff0c;即它最早可以于 Ti时刻开始降落&am…

redis数据类型:list

list 的相关命令配合使用的应用场景&#xff1a; 栈和队列&#xff1a;插入和弹出命令的配合&#xff0c;亦可实现栈和队列的功能 实现哪种数据结构&#xff0c;取决于插入和弹出命令的配合&#xff0c;如左插右出或右插左出&#xff1a;这两种种方式实现先进先出的数据结构&a…

IDEA中解决Edit Configurations中没有tomcat Server选项的问题

今天使用IDEA2024专业版的时候,发现Edit Configurations里面没有tomcat Server,最终找到解决方案。 一、解决办法 1、打开Settings 2、搜索tomcat插件 搜索tomcat插件之后,找到tomcat 发现tomcat插件处于未勾选状态,然后我们将其勾选保存即可。 二、结果展示 最后,再次编…

复习打卡大数据篇——Hadoop HDFS 02

目录 1. HDFS辅助工具 2. namenode安全模式 1. HDFS辅助工具 跨集群数据拷贝 当我们需要跨集群进行文件数据的拷贝时可以用&#xff1a; hadoop distcp 集群1的某个文件路径 要拷贝到集群2的地址路径 文件归档工具archive 由于HDFS的块的数量取决于文件的大小和数量&…

Mamba安装环境和使用,anaconda环境打包

什么是mamba Mamba是一个极速版本的conda&#xff0c;它是conda的C重新实现&#xff0c;使用多线程并行处理来加速包和依赖项的下载。 Mamba旨在提高安装、更新和卸载Python包的速度&#xff0c;同时保持与conda相同的兼容性和命令行接口。 Mamba的核心部分使用C实现&#xff…

Sigrity System Explorer Snip Via Pattern From Layout模式从其它设计中截取过孔模型和仿真分析操作指导

Sigrity System Explorer Snip Via Pattern From Layout模式从其它设计中截取过孔模型和仿真分析操作指导 Sigrity System Explorer Snip Via Pattern From Layout模式支持从其它设计中截取过孔模型用于仿真分析,同样以差分模板为例 具体操作如下 双击打开System Explorer软件…

顺序表的操作

注意位序和数组下标的关系 插入&#xff1a; 插入的时间复杂度&#xff1a; 最深层语句&#xff1a; 最好情况 最坏情况 平均情况 删除&#xff1a; 查找&#xff1a;