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

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.mzph.cn/news/905407.shtml

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

相关文章

【动态导通电阻】p-GaN HEMTs正向和反向导通下的动态导通电阻

2024 年,浙江大学的 Zonglun Xie 等人基于多组双脉冲测试方法,研究了两种不同技术的商用 p-GaN 栅极 HEMTs 在正向和反向导通模式以及硬开关和软开关条件下的动态导通电阻(RON)特性。实验结果表明,对于肖特基型 p-GaN 栅极 HEMTs,反向导通时动态 RON 比正向导通高 3%-5%;…

PDFMathTranslate:科学 PDF 文件翻译及双语对照工具

PDFMathTranslate&#xff1a;科学 PDF 文件翻译及双语对照工具 在科研和学习过程中&#xff0c;我们经常会遇到大量的英文 PDF 文献&#xff0c;翻译这些文献成为了一项繁琐且耗时的工作。PDFMathTranslate 是一款强大的科学 PDF 文件翻译及双语对照工具&#xff0c;它能够保…

Flutter PIP 插件 ---- 为iOS 重构PipController, Demo界面,更好的体验

接上文 Flutter PIP 插件 ---- 新增PipActivity&#xff0c;Android 11以下支持自动进入PIP Mode 项目地址 PIP&#xff0c; pub.dev也已经同步发布 pip 0.0.3&#xff0c;你的加星和点赞&#xff0c;将是我继续改进最大的动力 在之前的界面设计中&#xff0c;还原动画等体验一…

【Ansible】之inventory主机清单

前言 本篇博客主要解释Ansible主机清单的相关配置知识 一、inventory 主机清单 Inventory支持对主机进行分组&#xff0c;每个组内可以定义多个主机&#xff0c;每个主机都可以定义在任何一个或多个主机组内。 如果是名称类似的主机&#xff0c;可以使用列表的方式表示各个主机…

基于几何布朗运动的股价预测模型构建与分析

基于几何布朗运动的股价预测模型构建与分析 摘要 本文建立基于几何布朗运动的股价预测模型&#xff0c;结合极大似然估计与蒙特卡洛模拟&#xff0c;推导股价条件概率密度函数并构建动态预测区间。实证分析显示模型在标普500指数预测中取得89%的覆盖概率&#xff0c;波动率估…

【前端】【JavaScript】【总复习】四万字详解JavaScript知识体系

JavaScript 前端知识体系 &#x1f4cc; 说明&#xff1a;本大纲从基础到高级、从语法到应用、从面试到实战&#xff0c;分层级讲解 JavaScript 的核心内容。 一、JavaScript 基础语法 1.1 基本概念 1.1.1 JavaScript 的发展史与用途 1. 发展简史 1995 年&#xff1a;JavaS…

[Java实战]Spring Boot 3 整合 Apache Shiro(二十一)

[Java实战]Spring Boot 3 整合 Apache Shiro&#xff08;二十一&#xff09; 引言 在复杂的业务系统中&#xff0c;安全控制&#xff08;认证、授权、加密&#xff09;是核心需求。相比于 Spring Security 的重量级设计&#xff0c;Apache Shiro 凭借其简洁的 API 和灵活的扩…

PyTorch API 6 - 编译、fft、fx、函数转换、调试、符号追踪

文章目录 torch.compiler延伸阅读 torch.fft快速傅里叶变换辅助函数 torch.func什么是可组合的函数变换&#xff1f;为什么需要可组合的函数变换&#xff1f;延伸阅读 torch.futurestorch.fx概述编写转换函数图结构快速入门图操作直接操作计算图使用 replace_pattern() 进行子图…

可观测性方案怎么选?SelectDB vs Elasticsearch vs ClickHouse

可观测性&#xff08;Observability&#xff09;是指通过系统的外部输出数据&#xff0c;推断其内部状态的能力。可观测性平台通过采集、存储、可视化分析三大可观测性数据&#xff1a;日志&#xff08;Logging&#xff09;、链路追踪&#xff08;Tracing&#xff09;和指标&am…

机器人厨师上岗!AI在餐饮界掀起新风潮!

想要了解人工智能在其他各个领域的应用&#xff0c;可以查看下面一篇文章 《AI在各领域的应用》 餐饮业是与我们日常生活息息相关的行业&#xff0c;而人工智能&#xff08;AI&#xff09;正在迅速改变这个传统行业的面貌。从智能点餐到食材管理&#xff0c;再到个性化推荐&a…

Linux动态库静态库总结

静态库生成 g -c mylib.cpp -o mylib.o ar rcs libmylib.a mylib.o 动态库生成 g -fPIC -shared mylib.cpp -o libmylib.so -fPIC&#xff1a;生成位置无关代码&#xff08;Position-Independent Code&#xff09;&#xff0c;对动态库必需。 库文件使用&#xff1a; 静态库&…

通过user-agent来源判断阻止爬虫访问网站,并防止生成[ error ] NULL日志

一、TP5.0通过行为&#xff08;Behavior&#xff09;拦截爬虫并避免生成 [ error ] NULL 错误日志 1. 创建行为类&#xff08;拦截爬虫&#xff09; 在 application/common/behavior 目录下新建BlockBot.php &#xff0c;用于识别并拦截爬虫请求&#xff1a; <?php name…

OpenHarmony平台驱动开发(十五),SDIO

OpenHarmony平台驱动开发&#xff08;十五&#xff09; SDIO 概述 功能简介 SDIO&#xff08;Secure Digital Input and Output&#xff09;由SD卡发展而来&#xff0c;与SD卡统称为MMC&#xff08;MultiMediaCard&#xff09;&#xff0c;二者使用相同的通信协议。SDIO接口…

使用FastAPI和React以及MongoDB构建全栈Web应用03 全栈开发快速入门

一、什么是全栈开发 A full-stack web application is a complete software application that encompasses both the frontend and backend components. It’s designed to interact with users through a web browser and perform actions that involve data processing and …

Coco AI 开源应用程序 - 搜索、连接、协作、您的个人 AI 搜索和助手,都在一个空间中。

一、软件介绍 文末提供程序和源码下载 Coco AI 是一个统一的搜索平台&#xff0c;可将您的所有企业应用程序和数据&#xff08;Google Workspace、Dropbox、Confluent Wiki、GitHub 等&#xff09;连接到一个功能强大的搜索界面中。此存储库包含为桌面和移动设备构建的 Coco 应…

CSS经典布局之圣杯布局和双飞翼布局

目标&#xff1a; 中间自适应&#xff0c;两边定宽&#xff0c;并且三栏布局在一行展示。 圣杯布局 实现方法&#xff1a; 通过float搭建布局margin使三列布局到一行上relative相对定位调整位置&#xff1b; 给外部容器添加padding&#xff0c;通过相对定位调整左右两列的…

# 实时英文 OCR 文字识别:从摄像头到 PyQt5 界面的实现

实时英文 OCR 文字识别&#xff1a;从摄像头到 PyQt5 界面的实现 引言 在数字化时代&#xff0c;文字识别技术&#xff08;OCR&#xff09;在众多领域中发挥着重要作用。无论是文档扫描、车牌识别还是实时视频流中的文字提取&#xff0c;OCR 技术都能提供高效且准确的解决方案…

<C#>log4net 的配置文件配置项详细介绍

log4net 是一个功能强大的日志记录工具&#xff0c;通过配置文件可以灵活地控制日志的输出方式、格式、级别等。以下是对 log4net 配置文件常见配置项的详细介绍&#xff1a; 根元素 <log4net> 这是 log4net 配置文件的根元素&#xff0c;所有配置项都要包含在该元素内…

编译docker版openresty

使用alpine为基础镜像 # 使用Alpine作为基础镜像 FROM alpine:3.18# 替换为阿里云镜像源&#xff0c;并安装必要的依赖 RUN sed -i s|https://dl-cdn.alpinelinux.org/alpine|https://mirrors.aliyun.com/alpine|g /etc/apk/repositories && \apk add --no-cache \bui…

conda 输出指定python环境的库 输出为 yaml文件

conda 输出指定python环境的库 输出为 yaml文件。 有时为了项目部署&#xff0c;需要匹配之前的python环境&#xff0c;需要输出对应的python依赖库。 假设你的目标环境名为 myenv&#xff0c;运行以下命令&#xff1a; conda env export -n myenv > myenv_environment.ym…