【C++设计模式之Template Method Pattern】

news2025/7/17 0:11:24

C++设计模式之Template Method Pattern

  • 模式定义
  • 核心思想
  • 动机(Motivation)
  • 结构(Structure)
  • 实现步骤
  • 应用场景
  • 要点总结


模式定义

模式定义: 定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类中。Template Method使得子类可以不改变(复用)一个算法的结构即可重定义(override重写)该算法的某些特定步骤。
它定义了一个算法的骨架,将某些步骤的具体实现延迟到子类中。该模式通过固定算法结构,允许子类在不改变算法流程的前提下重新定义某些步骤。

核心思想

  • 不变流程,可变细节:将算法的公共逻辑封装在基类中,具体步骤的实现交给子类。
  • 避免重复代码:通过复用基类的模板方法,减少子类中的冗余逻辑。
  • 控制扩展点:明确哪些步骤允许子类重写,哪些必须固定。

动机(Motivation)

  • 在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
  • 如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?

结构(Structure)

在这里插入图片描述

实现步骤

  1. 定义抽象基类

基类中声明模板方法(通常为非虚函数),并定义算法的步骤接口(可以是纯虚函数或虚函数)

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";
	}
};
  1. 实现具体子类

子类重写基类中的步骤方法,提供具体实现

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";
	}
};
  1. 示例调用
    main.cpp
#include"concreteclass.h"

int main()
{
	ConcreteClassA objA;
	objA.templateMethod();   //调用固定流程:step1->step2->step3(默认)
	ConcreteClassB objB;
	objB.templateMethod();   //调用流程:step1->step2->step3(自定义)
}

  1. 输出结果
ConcreteClassA:step1
ConcreteClassA:step2
AbstractClass::step3(默认实现)
ConcreteClassB::step1
ConcreteClassB::step2
ConcreteClassB::step3

应用场景

  1. 框架设计:定义框架的流程(如初始化、运行、清理),允许用户自定义具体步骤,即定义抽象基类

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";
	}
};
  1. 数据处理流程:固定数据读取、处理、保存,允许自定义处理逻辑,即定义抽象基类*
#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方法。

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

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

相关文章

英伟达Blackwell架构重构未来:AI算力革命背后的技术逻辑与产业变革

——从芯片暴力美学到分布式智能体网络&#xff0c;解析英伟达如何定义AI基础设施新范式 开篇&#xff1a;当算力成为“新石油”&#xff0c;英伟达的“炼油厂”如何升级&#xff1f; 2025年3月&#xff0c;英伟达GTC大会上&#xff0c;黄仁勋身披标志性皮衣&#xff0c;宣布了…

深度拆解!MES如何重构生产计划与排产调度全流程?

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

信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(十八)

个人笔记整理---仅供参考 第十八章项目绩效域 18.1干系人绩效域 18.2团队绩效域 18.3开发方法和生命周期绩效域 18.5项目工作绩效域 18.6交付绩效域 18.7度量绩效域 18.8不确定绩效域

UniDevTools - UniApp(前端app)调试工具使用

使用介绍 | UniDevTools 兼容框架&#xff1a; Vue2jsvuexVue3tsvuex(pinia)√√ 兼容平台&#xff1a; H5APP微信小程序APP-NVUE其他小程序UniAppX√√√√(大部分功能支持)未测试 (待办中) 下载安装 将下载好的源码解压至项目根目录&#xff0c;文件夹命名为 devTools …

spring中的@Lazy注解详解

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

视觉-语言-动作模型:概念、进展、应用与挑战(上)

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

语义分割模型部署到嵌入式终端的通用操作流程

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

R1-Searcher:用强化学习解锁大语言模型检索新能力!

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

第一篇 世界观安全

目录 STRIDE模型 五大原则 一黑白名单 二最小权限原则 三纵深防御原则 四数据和代码分离 五不可预测原则 安全的问题本质是信任问题。 并且安全是一个持续的过程。 安全的三要素&#xff1a;机密性&#xff0c;完整性&#xff08;可以采用数字签名&#xff09;&#x…

mac M2能安装的虚拟机和linux系统系统

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

无偿帮写毕业论文

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

智能网联汽车“内外协同、虚实共生”的通信生态

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 钝感力的“钝”&#xff0c;不是木讷、迟钝&#xff0c;而是直面困境的韧劲和耐力&#xff0c;是面对外界…

Linux操作系统从入门到实战(六)Linux开发工具(上)详细介绍什么是软件包管理器,Linux下如何进行软件和软件包的安装、升级与卸载

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

物流无人机自动化装卸技术解析!

一、自动化装卸技术模块的技术难点 1. 货物多样性适配 物流场景中货物包装类型、尺寸、材质差异大&#xff0c;如农产品、医疗物资、工业设备等&#xff0c;要求装卸模块具备高度柔性化设计。例如&#xff0c;单元货物需视觉识别系统进行单个抓取&#xff0c;而整托货物需大…

IOT藍牙探測 C2 架構:社會工程/節點分離防追尋

BMC 地址:https://github.com/MartinxMax/bmc/releases/tag/V1.5 藍牙 MAC 偵測節點的物聯網分散式 C2 架構&#xff0c;可與 S-Cluster 交互。 場景 A&#xff1a;潛伏偵測 駭客組織會將 BMC 裝置秘密部署在目標建築物周圍&#xff08;例如牆外、通風口或垃圾間等隱蔽地點&…

FreeRTOS学习记录(变量命名规则全解、文件介绍)

目录 FreeRTOS 变量命名规则详解​ ​一、变量命名前缀规则​ &#xff08;一&#xff09;数据类型相关前缀​ &#xff08;二&#xff09;功能模块相关前缀​ &#xff08;三&#xff09;宏定义 二、变量命名与文件的关系​ &#xff08;一&#xff09;核心源文件中的变…

Qt 中 QWidget涉及的常用核心属性介绍

欢迎来到干货小仓库 一匹真正的好马&#xff0c;即使在鞭子的影子下&#xff0c;也能飞奔 1.enabled API说明isEnabled()获取到控件的可用状态setEnabled()设置控件是否可使用.true&#xff1a;可用&#xff0c;false&#xff1a;禁用 禁用&#xff1a;指该控件不能接收任何用…

Open CASCADE学习|由大量Edge构建闭合Wire:有序与无序处理的完整解析

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

linux 开发小技巧之git增加指令别名

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

一文读懂如何使用MCP创建服务器

如果你对MCP&#xff08;模型上下文协议&#xff09;一窍不通&#xff0c;在阅读本篇文章之前&#xff08;在获得对MCP深度认识之前&#xff09;&#xff0c;你可以理解为学习MCP就是在学习一个python工具库mcp&#xff0c;类似于其它python工具库一样&#xff0c;如numpy、sys…