C++设计模式 - 模板模式

devtools/2025/2/12 1:09:27/

一:概述

        模板方法(Template Method)是一种行为型设计模式。它定义了一个算法的基本框架,并且可能是《设计模式:可复用面向对象软件的基础》一书中最常用的设计模式之一。

        模板方法的核心思想很容易理解。我们需要定义一个包含多个固定步骤的算法框架。具体的实现类只能重写这些步骤,但不能改变整体框架。这些步骤通常被称为钩子方法(hook methods)。

 二:设计思想

  • 定义一个包含多个典型步骤的算法框架。
  • 子类可以调整这些步骤,但不能改变整体框架。

三:使用场景

  • 需要使用算法的不同版本。
  • 这些算法版本由相似的步骤组成。

四:模式结构

AbstractClass(抽象类)

  • 定义算法的结构,由多个步骤组成。
  • 算法的步骤可以是虚函数或纯虚函数。

ConcreteClass(具体类)

  • 根据需要重写算法的特定步骤。

五:代码示例

#include <iostream>// 抽象基类,定义模板方法
class Meal {
public:// 模板方法,final 关键字确保子类不能重写该方法void prepareMeal() {  boilWater();              // 步骤 1:烧水cook();                   // 步骤 2:烹饪,子类需要实现serve();                  // 步骤 3:上菜}virtual ~Meal() = default;private:void boilWater() {                // 步骤 1:烧水,所有餐食共享的步骤std::cout << "Boiling water\n";}virtual void cook() = 0;          // 步骤 2:烹饪,子类必须实现virtual void serve() = 0;         // 步骤 3:上菜,子类必须实现
};// 具体子类:制作汤
class Soup : public Meal {
private:void cook() override {            // 实现具体的烹饪步骤std::cout << "Cooking soup\n";}void serve() override {           // 实现具体的上菜步骤std::cout << "Serving soup\n";}
};// 具体子类:制作沙拉
class Salad : public Meal {
private:void cook() override {            // 实现具体的烹饪步骤std::cout << "Preparing salad\n";}void serve() override {           // 实现具体的上菜步骤std::cout << "Serving salad\n";}
};int main() {std::cout << "Preparing meal of Soup:\n";Meal* meal = new Soup();meal->prepareMeal();              // 调用模板方法,自动完成一系列步骤delete meal;std::cout << "\nPreparing meal of Salad:\n";meal = new Salad();meal->prepareMeal();              // 调用模板方法,自动完成一系列步骤delete meal;return 0;
}

六:相关模式

      模板方法模式和策略模式的使用场景非常相似。两者都允许提供算法的不同变体。模板方法模式通过子类化在类级别上实现,而策略模式通过对象组合在对象级别上实现。策略模式将不同的策略作为对象提供,因此可以在运行时交换策略。模板方法模式倒置了控制流,遵循好莱坞原则:“别找我们,我们来找你”。策略模式通常是一个黑盒,它允许你在不需要了解其细节的情况下替换策略。

七:优缺点

 优点

  • 通过创建新的子类,新的算法变体易于实现。
  • 算法中的共同步骤可以直接在接口类中实现。

缺点

  • 即使是算法的小变体,也需要创建一个新的类,这可能导致创建许多小类。
  • 算法框架是固定的,无法更改;不过,你可以通过将框架函数设为虚函数来克服这一限制。

参考:

1. https://zh.wikipedia.org/wiki/%E6%A8%A1%E6%9D%BF%E6%96%B9%E6%B3%95

2. The Template Method – MC++ BLOG


http://www.ppmy.cn/devtools/158072.html

相关文章

Maven Profile 配置:支持不同环境的构建

1. 什么是 Maven Profile&#xff1f; Maven Profile 是 Maven 提供的一种环境配置管理机制&#xff0c;可以根据不同的环境&#xff08;如开发环境、测试环境、生产环境&#xff09;定义不同的构建配置。 使用场景&#xff1a; 多环境配置&#xff1a;如 dev&#xff08;开…

Vue3 特点

不强制要求组件有根节点 // vue2 <template><div><h1>标题</h1><p>内容</p></div> </template>// vue3 <template><h1>标题</h1><p>内容</p> </template> 注意事项 虽然 Vue 3 不再强制…

windows中HyperV为ubuntu指定固定IP

1. 配置Windows主机的网络 打开“控制面板” -> “网络和共享中心” -> “更改适配器设置”。 找到与InternalSwitch对应的网络适配器&#xff08;通常名为vEthernet (InternalSwitch)&#xff09;。 右键点击适配器&#xff0c;选择“属性”。 双击“Internet协议版本…

【系统架构设计师】操作系统 ③ ( 存储管理 | 页式存储弊端 - 段式存储引入 | 段式存储 | 段表 | 段表结构 | 逻辑地址 的 合法段地址判断 )

文章目录 一、页式存储弊端 - 段式存储引入1、页式存储弊端 - 内存碎片2、页式存储弊端 - 逻辑结构不匹配3、段式存储引入 二、段式存储 简介1、段式存储2、段表3、段表 结构4、段内地址 / 段内偏移5、段式存储 优缺点6、段式存储 与 页式存储 对比 三、逻辑地址 的 合法段地址…

1、Spring Cloud Alibaba 入门指南

一、微服务架构与 Spring Cloud Alibaba 在当今数字化快速发展的时代&#xff0c;软件系统的规模和复杂性不断增加。传统的单体架构在面对高并发、高可用以及快速迭代需求时&#xff0c;逐渐显得力不从心。微服务架构应运而生&#xff0c;它将一个大型应用拆分成多个小型、独立…

vue基础(四)

一、计算属性 - computed computed&#xff08;计算属性&#xff09;在 Vue 2 和 Vue 3 中都能使用&#xff0c;主要用于处理依赖响应式数据的计算逻辑&#xff0c;它的值会根据依赖的变化自动更新&#xff0c;同时有缓存&#xff0c;比 methods 更高效。 1. 基本使用 示例&…

iOS pod install一直失败,访问github超时记录

** iOS pod install一直失败&#xff0c;访问github超时记录 ** 使用nslookup github.com 查看网页所对应的IP地址 nslookup github.com 然后在进行系统配置处理&#xff0c;使用sudo进行打开 sudo nano /etc/hosts添加查询到的IP地址和对应的域名信息 20.207.73.82 githu…

ffmpeg -devices

1. ffmpeg -devices -loglevel quiet 显示ffmpeg支持的设备&#xff0c;通常用于查看ffmpeg支持的硬件设备&#xff0c;比如Cuda、Atalas 2. 输出 Devices: D. Demuxing supported .E Muxing supported DE alsa ALSA audio output E caca caca (color ASCII art) output…