模板方法模式(Template Method)
模式结构图
说明
基本方法是模板方法的组成部分。基本方法分为一下三种:
- 抽象方法
- 由抽象类声明,由其具体子类实现。C++中就是纯虚函数。
- 具体方法
- 由抽象类或具体类声明并实现,子类可以进行覆盖也可以继承。C++中是虚函数。
- 钩子方法
- 由抽象类或具体类声明并实现,子类可能会加以扩展。
其中钩子方法比较特殊,通常在父类给出的实现是一个空实现,并以该实现作为方法的默认实现。当然,默认实现也可以是非空。
模板方法模式中,钩子方法分为两类。
第一类钩子方法可以与一些具体步骤“挂钩”,以确定在不同条件下执行模板方法中的不同步骤,这类钩子方法的返回值通常是boolean
类型的,这类方法一般为isXXX()
,用于对某个条件进行判断,如果条件满足则执行某一步骤,否则不执行。
如下所示:
void TemplateMethod::template()
{open();display();if(isPrint){print();}
}
bool TemplateMethod::isPrint()
{return true;
}
在代码中isPrint()
是钩子方法,它可以决定print()
方法是否执行,一般情况下,钩子方法返回值为true
,如果不希望某方法执行,可以在其子类中覆盖钩子方法,将其返回值改为false
。这种钩子方法可以控制方法的执行,对一个算法进行约束。
第二类钩子方法就是实现体为空的具体方法,子类可以根据需要覆盖或者继承这些钩子方法,与抽象方法相比,钩子方法的好处在于如果没有覆盖父类中定义的钩子方法,编译可以通过,但是如果没有覆盖父类中抽象方法,编译将报错。
子类的钩子方法覆盖父类的钩子方法,可以通过子类对父类方法的执行进行约束,实现对父类的反向控制。
模板方法模式适用场景
- 一次性实现一个算法的不变部分,并将可变行为留给子类来实现 。
- 各子类中公共的行为应被提取出来,并集中到一个公共父类中,以避免代码重复。首先需要识别现有代码中的不同之处,并且将不同之处分离为新的操作,然后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
- 对一些复杂的算法进行分割,将其算法中固定不变的部分设计为模板方法和父类具体方法,而一些可以改变的细节由其子类来实现。
- 控制子类的扩展。模板方法只在特定点调用钩子方法,这样就只允许在这些点进行扩展,也就是说对于某些方法,可以通过钩子方法来进行扩展,而对于不能进行扩展的方法也可以将其定义为
final
方法,对算法的扩展进行有效的控制和约束。
扩展
- 继承的使用
- 在扩展抽象层时采用继承,具体类之间的复用 以及 抽象层之间的相互调用则使用关联关系。
- 好莱坞原则
- 子类不需要调用父类,而通过父类来调用子类,将某些步骤的实现写在子类中,由父类来控制整个过程。
实例
银行业务办理
#include <iostream>
#include <vector>
using namespace std;class BankTemplateMethod {
public:virtual ~BankTemplateMethod() = default;virtual void take_number() final { cout << "取号" << endl;};virtual void transact() = 0;virtual void evaluate() final { cout << "反馈评分" << endl; };virtual void process() final {this->take_number();this->transact();this->evaluate();};
};class Deposit : public BankTemplateMethod {
public:void transact() override { cout << "存款" << endl;}
};class Withdraw : public BankTemplateMethod {
public:void transact() override { cout << "取款" << endl; }
};class Transfer : public BankTemplateMethod {
public:void transact() override { cout << "转账" << endl; }
};int main (void)
{vector<BankTemplateMethod *> banks{new Deposit(),new Withdraw(),new Transfer()};for (auto i : banks) {i->process();cout << "\n";}for (auto i : banks) {delete i;}
}
相关文章:
模板方法模式(Template Method)
模式结构图 说明 基本方法是模板方法的组成部分。基本方法分为一下三种: 抽象方法 由抽象类声明,由其具体子类实现。C中就是纯虚函数。 具体方法 由抽象类或具体类声明并实现,子类可以进行覆盖也可以继承。C中是虚函数。 钩子方法 由抽象类…...
C C++ typedef的使用
一、为基本数据类型起别名 typedef int myint; myint x 5; "myint"是"int"的别名,可以使用"myint"来代替"int"声明变量,这个很好理解,但是也很少有人这么用吧。 二、为结构体起别名 …...
Laravel框架03:DB类操作数据库
Laravel框架03:DB类操作数据库一、概述二、数据表的创建与配置三、增删改操作1. 增加信息2. 修改数据3. 删除数据四、查询操作1. 取出基本数据2. 取出单行数据3. 获取一个字段的值4. 获取多个字段的值5. 排序6. 分页五、执行任意的SQL语句一、概述 按照MVC的架构&a…...
数据结构期末复习总结(前章)
作者的话 作为一名计算机类的学生,我深知数据结构的重要性。在期末复习前,我希望通过这篇博客给大家一些复习建议。希望能帮助大家夯实数据结构的基础知识,并能够更好地掌握数据结构和算法的应用。 一、绪论 数据:信息的载体&am…...
设计环形队列
文章目录1.思路分析1.1队列空满分析1.2出队分析2.循环队列设计1.思路分析 1.1队列空满分析 首先我们假设一个长度为4的环形队列 队头front 队尾rear 当队列为空时 frontrear 当队列满时 frontrear 所以我们无法判断队列是满的或者空的 因此我们多加入一个空间使队列长度为5&am…...
面向对象之-接口鉴权
1 需求 1.1 需求背景 为了保证接口调用的安全性,我们希望设计实现一个接口调用鉴权功能,只有经过认证之后的系统才能调用我们的接口,没有认证过的系统调用我们的接口会被拒绝。 2 需求分析 2.1 基础分析 对于如何做鉴权这样一个问题&…...
Python 多进程多线程线程池进程池协程
目录 一、线程与进程很简单的介绍 1.1 线程与进程的区别 二、多进程Process 2.1 多进程与多线程的区别 2.2 多进程为啥要使用队列 2.3 控制进程运行顺序 2.3.1 join , 2.3.1 daemon 守护进程 2.4 进程id 2.5 进程 存活状态is_alive() 2.5 实现自定义多…...
【自然语言处理】基于句子嵌入的文本摘要算法实现
基于句子嵌入的文本摘要算法实现人们在理解了文本的含义后,很容易用自己的话对文本进行总结。但在数据过多、缺乏人力和时间的情况下,自动文本摘要则显得至关重要。一般使用自动文本摘要的原因包括: 减少阅读时间根据摘要,选择自…...
fiddler抓包
一、工具介绍Fiddler是一个通过代理的方式来进行抓包工具,运行时会在本地建立一个代理服务,默认地址:127.0.0.1:8888。Fiddler开启之后,配置本机代理,再打开IE浏览器,IE的PROXY会自动变成127.0.0.1:8888&am…...
【Linux】网络套接字编程
前言 在掌握一定的网络基础,我们便可以先从代码入手,利用UDP协议/TCP协议进行编写套接字程序,明白网络中服务器端与客户端之间如何进行连接并且通信的。 目录 一、了解源目的IP、端口、网络字节序、套接字 端口号: 套接字&…...
break与continue关键字
1.概述 不知道大家有没有这样一种感受哈,有的时候容易混淆break语句和continue语句的用法,总是模棱两可,不敢确定自己是否使用正确了。正好,我们本篇的重点就是break和continue关键字的用法。 2.使用场景 Java中为啥会诞生break…...
kafka使用入门案例与踩坑记录
每次用到kafka时都会出现各种奇怪的问题,综合实践,下面汇总下主要操作步骤: Docker镜像形式启动 zookeeper启动 docker run -d --name zookeeper -p 2181:2181 -t wurstmeister/zookeeperkafka启动 docker run --name kafka01 -p 9092:909…...
系统启动太慢,调优后我直呼Nice
问题背景最近在负责一个订单系统的业务研发,本来不是件困难的事。但是服务的启动时间很慢,慢的令人发指。单次启动的时间约在10多分钟左右,基本一次迭代、开发,大部分的时间都花在了启动项目上。忍无可忍的我,终于决定…...
java知识点
文章目录异常写法JVM加载反射访问private调用方法动态代理注解元数据:TargetRetention元注解泛型编写泛型擦拭法局限通配符无限定通配符(<?>)集合重写方法和实现类IO流字节与字符转换同步和异步可以设置编码的类Print*类Files时间与日期时区一种二种三种异常…...
文件的打开关闭和顺序读写
目录 一、文件的打开与关闭 (一)文件指针 (二) 文件的打开和关闭 二、文件的顺序读写 (一)fputc 1. 介绍 2. 举例 (二)fgetc 1. 介绍 2. 举例1 3. 举例2 (三&…...
(十八)操作系统-进程互斥的软件实现方法
文章目录一、知识总览二、单标志法三、双标志先检查法四、双标志后检查法五、Peterson算法六、总结一、知识总览 二、单标志法 算法思想:两个进程在访问临界区后,会把使用临界区的权限转交给另一个进程。也就是说每个进程进入临界区的权限只能被另一个进…...
2023年三月份图形化一级打卡试题
活动时间 从2023年3月1日至3月21日,每天一道编程题。 本次打卡的规则如下: 小朋友每天利用10~15分钟做一道编程题,遇到问题就来群内讨论,我来给大家答疑。 小朋友做完题目后,截图到朋友圈打卡并把打卡的截图发到活动群…...
linux 防火墙管理-firewalld
什么是Firewalld 当前很多linux系统中都默认使用 firewalld(Dynamic Firewall Manager of Linux systems,Linux系统的动态防火墙管理器)服务作为防火墙配置管理工具。 “firewalld”是firewall daemon。它提供了一个动态管理的防火墙&#x…...
2023年最新大厂开发面试题(滴滴,华为,京东,腾讯,头条)
2023年最新大厂开发面试题!!! 滴滴篇 B树、B-树的区别? 数据库隔离级别,幻读和不可重复读的区别? 有 hell, well, hello, world 等字符串组,现在问能否拼接成 helloworld,代码实现。 快排算…...
2023年三月份图形化三级打卡试题
活动时间 从2023年3月1日至3月21日,每天一道编程题。 本次打卡的规则如下: 小朋友每天利用10~15分钟做一道编程题,遇到问题就来群内讨论,我来给大家答疑。 小朋友做完题目后,截图到朋友圈打卡并把打卡的截图发到活动群…...
蓝桥杯算法模板
模拟散列表拉链法import java.io.*; import java.util.*; public class a1 {static int n;static int N100003;static int[] hnew int[N];static int[] enew int[N];static int[] nenew int[N]; static int idx; static void insert(int x){int k(x%NN)%N;e[idx]x;ne[idx]h[k];…...
python之并发编程
一、并发编程之多进程 1.multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。Python提供了multiprocessing。 multiprocess…...
Vue.js自定义事件的使用(实现父子之间的通信)
vue v-model修饰符:.lazy、.number、.trim $attrs数据的透传,在组件(这个是写在App.vue中),数据就透传到student组件中,在template中可以直接使用{{$attrs.students}}获取数据 通过defineProps定义的属性在attrs中就…...
第12天-商品维护(发布商品、商品管理、SPU管理)
1.发布商品流程 发布商品分为5个步骤: 基本信息规格参数销售属性SKU信息保存完成 2.发布商品-基本信息 2.1.会员等级-会员服务 2.1.1.会员服务-网关配置 在网关增加会员服务的路由配置 - id: member_routeuri: lb://gmall-memberpredicates:- Path/api/member/…...
动态分区分配计算
动态分区分配 内存连续分配管理分为: 单一连续分配固定分区分配动态分区分配(本篇所讲) 首次适应算法(First Fit,FF) 该算法又称最先适应算法,要求空闲分区按照首地址递增的顺序排列。 优点…...
【云原生】k8s的pod基本概念
一、资源限制 Pod 是 kubernetes 中最小的资源管理组件,Pod 也是最小化运行容器化应用的资源对象。一个 Pod 代表着集群中运行的一个进程。kubernetes 中其他大多数组件都是围绕着 Pod 来进行支撑和扩展 Pod 功能的,例如用于管理 Pod 运行的 StatefulSe…...
【史上最全面esp32教程】激光与食人鱼模块篇
文章目录食人鱼模块模块介绍连线说明操作激光模块模块介绍连线说明操作总结提示:以下是本篇文章正文内容,下面案例可供参考 食人鱼模块 模块介绍 采用食人鱼LED设计制作一个发光的电子模块,其实他的本质和LED无区别。 连线说明 名称接线…...
《代码整洁之道》二之有意义的命名
1.有意义的命名 1.1 名副其实 取个好名字需要花时间,但是价值远超取名的时间,一旦发现更好的名称就换掉旧的。这么做,读你代码的人都会很开心。 变量名、方法名、类名称需要清晰的告诉别人含义,如果名称需要注释来补充…...
天气预测demo
天气预测1 数据集介绍1.1 训练集1.2 测试集2 导入数据进行数据分析2.1 浏览数据2.2 探索数据2.2.1 查看数据类型1 数据集介绍 1.1 训练集 训练集中共有116369个样本,每个样本有23个特征,特征具体介绍如下: 列名解释Date:日期&a…...
HDMI协议介绍(四)--Video
目录 视频格式 RGB444 YUV444 YUV422 YUV420 Color Depth Video控制信号 Pixel Repetition HDMI支持多种视频格式和分辨率。以hdmi1.4和2.0协议来说,视频格式支持RGB444、YUV444、YUV422和YUV420,其中RGB444和YUV444一般都是要求支持的。 视频格式…...
制作网站电话/长春seo
HDLBits——Basics Simple wire 要求: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xVLSIS1l-1637764502113)(https://hdlbits.01xz.net/mw/thumb.php?fWire.png&width800)] Solution: module top_module( input …...
二维码网站建设/温州网站建设开发
GitLab CI/CD 是一个内置在 GitLab 中的工具,用于通过持续方法进行软件开发:Continuous Integration(CI):持续集成Continuous Delivery(CD):持续交付Continuous Deploymentÿ…...
大连网页模板建站/百度扫一扫
sql小计汇总 rollup用法实例分析更新时间:2009年06月26日 17:47:28 作者:rollup在oracle ,sql-server里面都有有。这里介绍sql server2005里面的一个使用实例:CREATE TABLE tb(province nvarchar(10),city nvarchar(10),score int)INSERT t…...
重庆博达建设集团股份有限公司网站/磁力棒
cmd中输入 netstat -ano 回车.可以查看本机开放的全部端口. 协议:分为TCP和UDP本地地址(Local Address):代表本机IP地址和打开的端口号外部地址(Foreign Address):远程计算机IP地址和端口号状态…...
响应式 wordpress/友情连接
首先理解三个dom元素,分别是:clientHeight、offsetHeight、scrollTop。 clientHeight:这个元素的高度,占用整个空间的高度,所以,如果一个div有滚动条,那个这个高度则是不包括滚动条没显示出来的…...