模板方法模式-C语言实现

代码实现:

#include <stdio.h>// 定义抽象基类
typedef struct {void (*step1)(void);void (*step2)(void);void (*step3)(void);
} AbstractClass;// 具体实现类1
void concreteStep1() {printf("Concrete Step 1\n");
}void concreteStep2() {printf("Concrete Step 2\n");
}void concreteStep3() {printf("Concrete Step 3\n");
}// 具体实现类2
void anotherConcreteStep1() {printf("Another Concrete Step 1\n");
}void anotherConcreteStep2() {printf("Another Concrete Step 2\n");
}void anotherConcreteStep3() {printf("Another Concrete Step 3\n");
}// 模板方法
void templateMethod(AbstractClass* obj) {obj->step1();obj->step2();obj->step3();
}int main() {// 创建具体实现类1的对象并调用模板方法AbstractClass obj1 = {concreteStep1, concreteStep2, concreteStep3};templateMethod(&obj1);// 创建具体实现类2的对象并调用模板方法AbstractClass obj2 = {anotherConcreteStep1, anotherConcreteStep2, anotherConcreteStep3};templateMethod(&obj2);return 0;
}

在上面的示例代码中,首先定义了一个抽象基类AbstractClass,其中包含了三个函数指针,对应模板方法中的三个步骤。然后定义了具体实现类concreteStep1concreteStep2concreteStep3,以及另一个具体实现类anotherConcreteStep1anotherConcreteStep2anotherConcreteStep3,它们分别实现了抽象基类中的三个步骤。

接下来定义了模板方法templateMethod,它接收一个抽象基类对象作为参数,并依次调用对象的三个函数指针,完成算法的骨架部分。最后,在main函数中创建了两个不同的具体实现类的对象,并调用模板方法进行测试。

模板方法模式将算法的骨架和具体步骤的实现进行了解耦,通过在抽象基类中定义模板方法,并使用函数指针回调具体实现类的函数来实现多态性,可以灵活地扩展和定制算法的具体步骤。

模板方法模式是一种典型的行为型设计模式,其主要优缺点如下:

优点:

  1. 封装不变部分:将算法的骨架和具体实现分离,把不变的部分封装到父类中,可以提高代码复用性和可维护性。
  2. 提高可扩展性:子类可以通过重写父类的钩子方法,来改变算法的某些步骤,从而增强了模板方法的灵活性和可扩展性。
  3. 便于维护:模板方法模式使得算法的各个步骤都有明确的定义,易于调试和维护。

缺点:

  1. 增加了类的数量:为了实现模板方法模式,需要定义抽象类或接口,以及具体实现类,会增加类的数量和层次。
  2. 限制了继承的使用:由于模板方法模式采用了父类调用子类的方式,因此对子类的继承有一定的限制,子类必须遵循父类定义的算法骨架。
  3. 不适合复杂算法:如果算法的步骤太多或者太复杂,可能会导致模板方法变得过于庞大和复杂,难以维护和扩展。

适用场景:

  1. 算法的骨架已经确定,但是某些步骤的具体实现可能不同。
  2. 需要封装一些复杂的流程,使得屏蔽细节,提高代码复用性,以及便于维护。
  3. 具有多个子类共同实现某个方法,并且这些子类中的部分步骤相同,部分步骤不同。

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

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

相关文章

Qt5的事件处理函数有哪些?

2023年11月29日&#xff0c;周三上午 通过查看QWidget的定义可知&#xff0c;事件处理函数有&#xff1a; bool event(QEvent *event) override;virtual void mousePressEvent(QMouseEvent *event);virtual void mouseReleaseEvent(QMouseEvent *event);virtual void mouseDou…

[个人笔记] Git的CLI笔录

Git - CLI笔录 Git的CLI笔录 Git - CLI笔录Git的CLI笔录 Git的CLI笔录 origin: 表示远程仓库节点名称。 当有多个远程仓库时 可新增远程仓库节点名称如 new_origin | new_remote origin/HEAD: 表示当前Git仓库默认分支的引用&#xff0c;通常指向origin/master或origin/main g…

11.27二叉查找树,遍历二叉树,层序(判断是不是完全二叉树),根据遍历序列重构二叉树,递归输入建树(树的定义,结构体细节,typedef)

如果left<right&#xff0c;就表明其之间还有元素&#xff0c;即左右指针重合&#xff0c;区间只有一个元素也被包含其中&#xff1b; left<right,就表明递归过程中&#xff0c;只允许区间有两个及以上的元素&#xff0c;不允许区间只有一个元素&#xff0c;那么对应地&…

AB|如何正确从罗克韦尔官网下载资料?

哈喽呀&#xff0c;大家好&#xff0c;我是雷工&#xff01; 作为工控行业的从业者&#xff0c;可能要和各个厂家的中控系统、PLC、触摸屏、变频器、等软硬件产品打交道。 虽然从业十余年&#xff0c;但也不可能接触使用过所有的工控产品。还有海量的产品是没有接触过的。 但很…

Programming Abstractions in C阅读笔记:p202-p234

《Programming Abstractions in C》学习第65天&#xff0c;p202-p234总结。 一、技术总结 完成第五章学习&#xff0c;第五章介绍递归在实际问题中的进一步应用&#xff0c;例如汉诺塔问题&#xff0c;数学中的排列问题&#xff0c;更有难度。使用递归解决问题时有时候需要借…

TOD和PPS精确时间同步技术

介绍 PPS和TOD PPS和TOD是两种用于精确时间同步的技术&#xff0c;它们在许多领域都有广泛的应用&#xff0c;总的来说&#xff0c;PPS和TOD被广泛应用于各种需要高度精确时间同步的领域&#xff0c;包括通信、测量、测试、系统集成和计算机网络等。 一、PPS PPS&#xff08…

“华为杯”研究生数学建模竞赛2019年-【华为杯】C题:视觉情报信息分析(附Python代码实现)

目录 摘 要: 一、问题重述 1.1 背景描述 1.2 要解决的问题 二、符号说明

【专题】支持向量机(Support Vector Machines,SVM)

​​​​​ ​​ 支持向量机&#xff08;Support Vector Machines&#xff0c;SVM&#xff09;是一种强大的监督学习模型&#xff0c;常用于分类、回归和异常值检测任务。它的核心思想是通过构建一个最大间隔超平面来有效地分隔不同类别的数据点。 在SVM中&#xff0c;数据点…

Mysql8.1.0 安装问题-缺少visual studio 2019x64组件

缺少visual studio x64组件的问题 使用Mysql8以上的安装包mysql-8.1.0-winx64.msi进行安装&#xff0c; 提示缺少visual studio 2019 x64可再发行组件 在微软官网下载vc可再发行程序包 Microsoft Visual C 可再发行程序包最新支持的下载 在Visual Studio 2015、2017、2019 和…

使字符串的单词倒序输出表示

题目 任务描述 本关任务&#xff1a;请实现函数 revWordoder&#xff0c;能够将 pa 指向的单词表字符串中的所有单词&#xff0c;按相反顺序放入 pb&#xff0c;同时去除多余的空格&#xff0c;单词之间只留一个空格. 例如 pa 中为 red blue, 则调用函数后&#xff0c;pb 中为b…

MIT线性代数笔记-第17讲-正交矩阵,Schmidt正交化

目录 17.正交矩阵&#xff0c; S c h m i d t Schmidt Schmidt正交化打赏 17.正交矩阵&#xff0c; S c h m i d t Schmidt Schmidt正交化 “标准”经常表示单位长度 标准正交基&#xff1a;由两两正交的单位向量组成的基 将标准正交基中的元素记作 q ⃗ 1 , q ⃗ 2 , ⋯ , q …

基于FactoryBean、实例工厂、静态工厂创建Spring中的复杂对象

&#x1f609;&#x1f609; 学习交流群&#xff1a; ✅✅1&#xff1a;这是孙哥suns给大家的福利&#xff01; ✨✨2&#xff1a;我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 &#x1f96d;&#x1f96d;3&#xff1a;QQ群&#xff1a;583783…

公司网站遇到HTTPS攻击,有什么办法解决

随着互联网的不断发展和进步&#xff0c;Web应用程序的重要性不断提升。Web应用程序往往需要承载大量的用户数据&#xff0c;在传输过程中&#xff0c;为了保护数据安全&#xff0c;往往使用HTTPS协议进行数据加密。但是&#xff0c;HTTPS协议也面临着各种攻击的威胁&#xff0…

会声会影2024旗舰版系统配置要求及格式支持

会声会影2024旗舰版是一款广受欢迎的视频编辑软件&#xff0c;它的最新版本&#xff0c;会声会影2023&#xff0c;已经发布。在这篇文章中&#xff0c;我们将探讨会声会影2024旗舰版系统配置要求及格式支持 会声会影2024是一款专业的视频剪辑软件&#xff0c;能够帮助用户制作高…

如何在h5和小程序中适配iphoneX及更高版本全面屏底部的安全区

关键词 IOS 前言 在项目开发的过程中&#xff0c;需要IOS全面屏底部安全区适配 步骤 h5需要设置页面属性&#xff1a; <meta name"viewport"content"widthdevice-width, initial-scale1, maximum-scale1, user-scalableno,viewport-fitcover">2.…

geemap学习笔记016:获取图像的基本属性和描述性信息

前言 遥感数据中通常包含众多信息&#xff0c;例如图像获取的时间、云覆盖量、以及每个波段的最大值最小值等等。 1 导入库并显示地图 import ee import geemapMap geemap.Map() Map2 添加图像数据 centroid ee.Geometry.Point([-122.4439, 37.7538]) #创建一个点坐标lan…

Spark SQL,DF,RDD cache常用方式

RDD中的cache 调用cache方法 val testRDD sc.parallelize(Seq(elementA, elementB, elementC)).map(x > (x._1, x._2)).setName("testRDD")testRDD.cache() dataframe中的cache 利用catalog以表的形式对数据进行缓存 import org.apache.spark.SparkConf impo…

腾讯面试真题(C语言)

一.题目 求123...n&#xff0c;要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句&#xff08;A?B:C&#xff09;。 二.题目剖析 首先题目要求不能用乘除&#xff0c;那么&#xff08;首相末项&#xff09;*项数/2就不能用&#xff0c;其次不…

springcloud==openfeign

单独使用 创建一个服务端 import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.Path…

浅析函数防抖节流

防抖和节流都是前端开发中常用的优化性能的技术。 一、定义 防抖&#xff1a; 防抖指的是在事件触发后&#xff0c;在规定的时间内若再次触发&#xff0c;则重新计时&#xff0c;直到规定时间内没有再次触发事件&#xff0c;才执行事件处理。这样可以避免在短时间内频繁地触发…