【C++设计模式之Template Method Pattern】
C++设计模式之Template Method Pattern
- 模式定义
- 核心思想
- 动机(Motivation)
- 结构(Structure)
- 实现步骤
- 应用场景
- 要点总结
模式定义
模式定义: 定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类中。Template Method使得子类可以不改变(复用)一个算法的结构即可重定义(override重写)该算法的某些特定步骤。
它定义了一个算法的骨架,将某些步骤的具体实现延迟到子类中。该模式通过固定算法结构,允许子类在不改变算法流程的前提下重新定义某些步骤。
核心思想
- 不变流程,可变细节:将算法的公共逻辑封装在基类中,具体步骤的实现交给子类。
- 避免重复代码:通过复用基类的模板方法,减少子类中的冗余逻辑。
- 控制扩展点:明确哪些步骤允许子类重写,哪些必须固定。
动机(Motivation)
- 在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
- 如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?
结构(Structure)
实现步骤
- 定义抽象基类
基类中声明模板方法(通常为非虚函数),并定义算法的步骤接口(可以是纯虚函数或虚函数)
abstractclass.h
#include<iostream>//定义抽象基类
class AbstractClass {
public:virtual ~AbstractClass() = default;//模板方法:定义算法骨架(不可被子类重写)void templateMethod() {step1();step2();step3();}
protected://具体步骤(子类必须实现的接口)virtual void step1() = 0; //纯虚函数virtual void step2() = 0;virtual void step3() {std::cout << "AbstractClass::step3(默认实现)\n";}
};
- 实现具体子类
子类重写基类中的步骤方法,提供具体实现
concreteclass.h
#include"abstractclass.h"
class ConcreteClassA :public AbstractClass {
protected:void step1()override {std::cout << "ConcreteClassA:step1 \n";}void step2()override {std::cout << "ConcreteClassA:step2 \n";}//step3使用基类默认实现
};class ConcreteClassB :public AbstractClass {
protected:void step1() override {std::cout << "ConcreteClassB::step1\n";}void step2() override {std::cout << "ConcreteClassB::step2\n";}void step3() override {std::cout << "ConcreteClassB::step3\n";}
};
- 示例调用
main.cpp
#include"concreteclass.h"int main()
{ConcreteClassA objA;objA.templateMethod(); //调用固定流程:step1->step2->step3(默认)ConcreteClassB objB;objB.templateMethod(); //调用流程:step1->step2->step3(自定义)
}
- 输出结果
ConcreteClassA:step1
ConcreteClassA:step2
AbstractClass::step3(默认实现)
ConcreteClassB::step1
ConcreteClassB::step2
ConcreteClassB::step3
应用场景
- 框架设计:定义框架的流程(如初始化、运行、清理),允许用户自定义具体步骤,即定义抽象基类
gameframework.h
#pragma once
#include<iostream>
class GameFramework {
public:void run() { //模板方法initialize();mainLoop();shutdown();}protected:virtual void initialize() = 0; //子类实现初始化逻辑virtual void mainLoop() = 0; //子类实现主循环逻辑virtual void shutdown() { //默认实现std::cout << "GameFramework::shutdown \n";}
};
- 数据处理流程:固定数据读取、处理、保存,允许自定义处理逻辑,即定义抽象基类*
#pragma once
#include<iostream>
class DataProcessor {
public:void process() {//模板方法loadData();analyzeData();saveResult();}protected:virtual void loadData() = 0;virtual void analyzeData() = 0;virtual void saveResult() {std::cout << "Data saved to default path. \n";}
};
要点总结
- Template Method模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
- 除了可以灵活应对子步骤的变化外,“不要调用我,让我来调用你”的反向控制结构是Template Method的典型应用。
- 在具体实现方面,被Template Method调用的虚方法可以具有实现,也可以没有任何实现(抽象方法、纯虚方法),但一般推荐将它们设置为protected方法。
相关文章:

【C++设计模式之Template Method Pattern】
C设计模式之Template Method Pattern 模式定义核心思想动机(Motivation)结构(Structure)实现步骤应用场景要点总结 模式定义 模式定义: 定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类中。Template Method使得子…...
JVM对象头中的锁信息机制详解
JVM对象头中的锁信息机制详解 Java中的对象锁机制是高性能并发的基石,而这一切的底层实现都离不开对象头中的 Mark Word 字段。本文将系统梳理JVM对象头中锁信息的存储与演化机制,解析锁升级与批量重偏向优化原理,并通过JOL工具实战验证对象…...
Java设计模式之适配器模式:从入门到精通
适配器模式(Adapter Pattern)是Java中最常用的结构型设计模式之一,它像一座桥梁连接两个不兼容的接口,使得原本由于接口不兼容而不能一起工作的类可以协同工作。本文将全面深入地解析适配器模式,从基础概念到高级应用,包含丰富的代码示例、详细注释、使用场景分析以及多维对…...

英伟达Blackwell架构重构未来:AI算力革命背后的技术逻辑与产业变革
——从芯片暴力美学到分布式智能体网络,解析英伟达如何定义AI基础设施新范式 开篇:当算力成为“新石油”,英伟达的“炼油厂”如何升级? 2025年3月,英伟达GTC大会上,黄仁勋身披标志性皮衣,宣布了…...
【自定义指令】(el-table表格内容自动轮播)
// el-table 自动轮播 import { nextTick } from vue; export default {bind(el, binding) {const time binding.value?.time || 100;let speed binding.value?.speed || 1;const loop binding.value?.loop || true;const timeLoop binding.value?.timeLoop || true;co…...

深度拆解!MES如何重构生产计划与排产调度全流程?
☂引言 在制造业数字化转型浪潮中,生产计划与排产调度的精准性直接决定企业竞争力。深蓝易网MES系统通过智能化调度与全流程管控,帮助企业破解排产难题,实现资源高效协同与生产透明化管理,为制造企业打造柔性化、敏捷化的生产体系…...

信息系统项目管理师-软考高级(软考高项)2025最新(十八)
个人笔记整理---仅供参考 第十八章项目绩效域 18.1干系人绩效域 18.2团队绩效域 18.3开发方法和生命周期绩效域 18.5项目工作绩效域 18.6交付绩效域 18.7度量绩效域 18.8不确定绩效域...

UniDevTools - UniApp(前端app)调试工具使用
使用介绍 | UniDevTools 兼容框架: Vue2jsvuexVue3tsvuex(pinia)√√ 兼容平台: H5APP微信小程序APP-NVUE其他小程序UniAppX√√√√(大部分功能支持)未测试 (待办中) 下载安装 将下载好的源码解压至项目根目录,文件夹命名为 devTools …...
WebRTC工作原理详细介绍、WebRTC信令交互过程和WebRTC流媒体传输协议介绍
简介 WebRTC(Web Real-Time Communication)是一项允许在网页浏览器之间进行音视频通信的技术,基本不需要安装额外的插件。它的核心特点是支持低延迟的点对点(P2P)通讯,常用于视频聊天、实时文件共享、多人…...
Docker快速入门与应用
1. 什么是 Docker? Docker 就像一个“魔法箱子”,可以把你开发的应用(代码、环境、配置)打包成一个标准化的容器,这个容器可以在任何支持 Docker 的系统上运行,无需担心环境差异导致的问题。 类比…...
Spring Boot 启动原理的核心机制
一、核心启动流程概览 Spring Boot 的启动流程可概括为 7 个关键阶段: 1. 加载启动类 (Main Class) 2. 初始化 SpringApplication 实例 3. 加载配置 & 准备环境 (Environment) 4. 创建 ApplicationContext(容器) 5. 刷新容器&#…...

spring中的@Lazy注解详解
一、核心功能与作用 Lazy 注解是 Spring 框架中用于延迟 Bean 初始化的核心工具,通过将 Bean 的创建推迟到首次使用时,优化资源利用和启动性能。其核心功能包括: 延迟初始化 默认情况下,Spring 在容器启动时立即初始化所有单例 …...

视觉-语言-动作模型:概念、进展、应用与挑战(上)
25年5月来自 Cornell 大学、香港科大和希腊 U Peloponnese 的论文“Vision-Language-Action Models: Concepts, Progress, Applications and Challenges”。 视觉-语言-动作 (VLA) 模型标志着人工智能的变革性进步,旨在将感知、自然语言理解和具体动作统一在一个计…...

语义分割模型部署到嵌入式终端的通用操作流程
以下是语义分割模型部署到嵌入式终端的通用操作流程,结合不同硬件平台(如华为Atlas、地平线J5、树莓派等)的共性需求整理而成: 一、环境准备与工具链配置 1. 嵌入式开发环境搭建 安装交叉编译工具链(如ARM-GCC&…...

R1-Searcher:用强化学习解锁大语言模型检索新能力!
R1-Searcher:用强化学习解锁大语言模型检索新能力! 大语言模型(LLMs)发展迅猛,却常因依赖内部知识而在复杂问题上“栽跟头”。今天解读的论文提出R1-Searcher框架,通过强化学习提升LLMs检索能力。它表现超…...

第一篇 世界观安全
目录 STRIDE模型 五大原则 一黑白名单 二最小权限原则 三纵深防御原则 四数据和代码分离 五不可预测原则 安全的问题本质是信任问题。 并且安全是一个持续的过程。 安全的三要素:机密性,完整性(可以采用数字签名)&#x…...
RNN(循环神经网络)原理与结构
1 RNN(循环神经网络)原理与结构 循环神经网络(Recurrent Neural Network, RNN)是一类专门用于处理序列数据(如时间序列、文本、语音等)的深度学习模型。与传统的前馈神经网络不同,RNN在每个时间…...

mac M2能安装的虚拟机和linux系统系统
目前网上的资料大多错误,能支持M2的很少。 推荐安装的改造过的centos7也无法进行yum操作,建议安装centos8 VMware Fusion下载地址: https://pan.baidu.com/s/14v3Dy83nuLr2xOy_qf0Jvw 提取码: jri4 centos8下载地址: https://…...

无偿帮写毕业论文
以下教程教你如何利用相关网站和AI免费帮你写一个毕业论文。毕竟毕业论文只要过就行,脱产学习这么多年,终于熬出头了,完成毕设后有空就去多看看亲人好友,祝好! 一、找一个论文模板(最好是overleaf) 废话不多说&#…...

智能网联汽车“内外协同、虚实共生”的通信生态
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界…...

Linux操作系统从入门到实战(六)Linux开发工具(上)详细介绍什么是软件包管理器,Linux下如何进行软件和软件包的安装、升级与卸载
Linux操作系统从入门到实战(六)Linux开发工具(上)详细介绍什么是软件包管理器,Linux下如何进行软件和软件包的安装、升级与卸载 前言一、 软件包管理器1.1 传统安装方式的麻烦:从源代码说起1.2 软件包&…...

物流无人机自动化装卸技术解析!
一、自动化装卸技术模块的技术难点 1. 货物多样性适配 物流场景中货物包装类型、尺寸、材质差异大,如农产品、医疗物资、工业设备等,要求装卸模块具备高度柔性化设计。例如,单元货物需视觉识别系统进行单个抓取,而整托货物需大…...
基于构件的开发方法与传统开发方法的区别
在软件开发领域,基于构件的开发方法和传统开发方法有着截然不同的特点与应用效果,这些差异显著影响着项目的实施过程与最终成果。下面,我们将从多个关键维度展开对比分析。 一、开发模式:线性搭建与模块组装 传统开发方法遵循线性的、自顶向下的流程,就像搭建一座高楼…...
详解 IRC协议 及客户端工具 WeeChat 的使用
本文将详细介绍 Internet Relay Chat(IRC)协议及其历史、基本概念、核心功能,以及流行的 IRC 客户端 WeeChat 的安装、配置和使用方法。内容力求准确、详尽,涵盖 IRC 的技术背景、使用场景,以及 WeeChat 的高级功能和实…...

IOT藍牙探測 C2 架構:社會工程/節點分離防追尋
BMC 地址:https://github.com/MartinxMax/bmc/releases/tag/V1.5 藍牙 MAC 偵測節點的物聯網分散式 C2 架構,可與 S-Cluster 交互。 場景 A:潛伏偵測 駭客組織會將 BMC 裝置秘密部署在目標建築物周圍(例如牆外、通風口或垃圾間等隱蔽地點&…...
Koa知识框架
一、核心概念 1. 基本特点 由 Express 原班人马开发的下一代 Node.js Web 框架 基于中间件的洋葱圈模型 轻量级核心(仅约 600 行代码) 完全使用 async/await 异步流程控制 没有内置任何中间件,高度可定制 2. 核心对象 Application (Ko…...

FreeRTOS学习记录(变量命名规则全解、文件介绍)
目录 FreeRTOS 变量命名规则详解 一、变量命名前缀规则 (一)数据类型相关前缀 (二)功能模块相关前缀 (三)宏定义 二、变量命名与文件的关系 (一)核心源文件中的变…...

Qt 中 QWidget涉及的常用核心属性介绍
欢迎来到干货小仓库 一匹真正的好马,即使在鞭子的影子下,也能飞奔 1.enabled API说明isEnabled()获取到控件的可用状态setEnabled()设置控件是否可使用.true:可用,false:禁用 禁用:指该控件不能接收任何用…...

Open CASCADE学习|由大量Edge构建闭合Wire:有序与无序处理的完整解析
在CAD建模中,构建闭合的Wire(线框)是拓扑结构生成的基础操作。OpenCascade(OCCT)作为强大的几何建模库,支持从离散的Edge(边)构建Wire,但在实际应用中,边的有序性直接影响构建的成功率。本文将详细探讨有序与无序两种场景下的实现方法,并提供完整代码示例。 一、有序…...

linux 开发小技巧之git增加指令别名
众所周知,git的指令执行时都得敲好几个字符才能补充上来,比如常用的git status,是不是要将全部的字符一个个地在键盘敲上来,有没有更懒惰点办法,可以将经常用到的git命令通过其他的别名的方式填充,比如刚刚…...