C++实现设计模式---模板方法模式 (Template Method)

news/2025/1/16 20:23:13/

模板方法模式 (Template Method)

模板方法模式 是一种行为型设计模式,它定义了一个操作中的算法骨架,将某些步骤的实现延迟到子类。通过模板方法,子类可以在不改变算法结构的情况下重新定义算法的某些步骤。


意图

  • 在一个方法中定义算法的骨架,而将某些具体步骤延迟到子类中实现。
  • 让子类可以在不改变算法整体结构的情况下重新定义算法的某些步骤。

使用场景

  1. 多个类有相同的操作步骤,但具体实现不同
    • 当多个类的操作有一致的结构,但实现不同,可以使用模板方法模式
  2. 希望控制算法的结构
    • 父类定义算法骨架,子类实现具体步骤。
  3. 避免代码重复
    • 将公共逻辑抽取到父类中,具体逻辑在子类中实现。

参与者角色

  1. 抽象类 (AbstractClass)
    • 定义算法的骨架,并包含一个或多个抽象方法,子类需要实现这些方法。
    • 提供一个模板方法,定义算法的整体结构。
  2. 具体类 (ConcreteClass)
    • 实现抽象类中的抽象方法,提供算法的具体步骤。

示例代码

以下代码展示了模板方法模式的实现,用于模拟制作饮品的过程。不同的饮品(如茶和咖啡)有相同的制作步骤,但某些步骤的实现不同。

#include <iostream>// 抽象类:饮品
class Beverage {
public:virtual ~Beverage() = default;// 模板方法:定义饮品制作的算法骨架void prepareRecipe() {boilWater();           // 1. 煮沸水brew();                // 2. 冲泡pourInCup();           // 3. 倒入杯中if (customerWantsCondiments()) { // 4. 是否添加调料addCondiments();   // 添加调料}}protected:// 基本操作void boilWater() {std::cout << "将水煮沸。
";}void pourInCup() {std::cout << "将饮品倒入杯中。
";}// 抽象操作:由子类实现virtual void brew() = 0;virtual void addCondiments() = 0;// Hook(钩子方法):子类可选择重写virtual bool customerWantsCondiments() {return true; // 默认需要添加调料}
};// 具体类:茶
class Tea : public Beverage {
protected:void brew() override {std::cout << "用热水浸泡茶叶。
";}void addCondiments() override {std::cout << "添加柠檬。
";}
};// 具体类:咖啡
class Coffee : public Beverage {
protected:void brew() override {std::cout << "用热水冲泡咖啡。
";}void addCondiments() override {std::cout << "添加牛奶和糖。
";}// 重写钩子方法bool customerWantsCondiments() override {char answer;std::cout << "是否需要添加牛奶和糖?(y/n): ";std::cin >> answer;return (answer == 'y' || answer == 'Y');}
};// 客户端代码
int main() {std::cout << "制作茶:
";Tea tea;tea.prepareRecipe();std::cout << "
制作咖啡:
";Coffee coffee;coffee.prepareRecipe();return 0;
}

代码解析

1. 抽象类 (Beverage)
  • 定义了模板方法 prepareRecipe,它包含制作饮品的算法骨架。
  • 提供了基本操作(如 boilWaterpourInCup),以及抽象操作(如 brewaddCondiments),具体实现由子类完成。
  • 包含钩子方法 customerWantsCondiments,允许子类自定义是否执行某些步骤。
class Beverage {
public:virtual ~Beverage() = default;void prepareRecipe() {boilWater();brew();pourInCup();if (customerWantsCondiments()) {addCondiments();}}protected:void boilWater() { std::cout << "将水煮沸。
"; }void pourInCup() { std::cout << "将饮品倒入杯中。
"; }virtual void brew() = 0;virtual void addCondiments() = 0;virtual bool customerWantsCondiments() { return true; }
};
2. 具体类 (Tea, Coffee)
  • Tea
    • 实现了 brewaddCondiments 方法,定义了茶的制作方式。
  • Coffee
    • 实现了 brewaddCondiments 方法,定义了咖啡的制作方式。
    • 重写了 customerWantsCondiments 方法,允许用户选择是否添加调料。
class Tea : public Beverage {
protected:void brew() override { std::cout << "用热水浸泡茶叶。
"; }void addCondiments() override { std::cout << "添加柠檬。
"; }
};
3. 客户端代码
  • 客户端通过调用模板方法 prepareRecipe 来制作饮品,具体实现由子类决定。
int main() {Tea tea;tea.prepareRecipe();Coffee coffee;coffee.prepareRecipe();
}

优缺点

优点
  1. 复用代码
    • 将公共逻辑抽取到模板方法中,减少代码重复。
  2. 灵活性
    • 子类可以通过实现抽象方法或重写钩子方法来自定义算法的某些步骤。
  3. 控制算法结构
    • 父类定义算法结构,保证子类不会破坏算法整体逻辑。
缺点
  1. 对子类的依赖
    • 子类需要实现抽象方法,可能导致类的数量增加。
  2. 模板方法难以扩展
    • 如果模板方法需要修改,可能会影响所有子类。

适用场景

  1. 多个子类有相同的算法结构,但实现不同
    • 如制作不同饮品的过程。
  2. 希望控制算法的执行流程
    • 父类定义算法骨架,子类实现具体步骤。
  3. 需要扩展算法的某些步骤
    • 通过子类实现具体步骤,保证算法结构不变。

总结

模板方法模式通过定义算法的骨架,将具体实现延迟到子类中,从而实现代码复用和灵活扩展。它特别适用于算法结构固定但某些步骤实现不同的场景。


http://www.ppmy.cn/news/1563702.html

相关文章

备战蓝桥杯:树的存储与遍历(dfs和bfs)

树的概念 树的逻辑结构是树形结构&#xff0c;和我们之前的线性结构又不太一样了&#xff0c;是一种一对多的关系 树的结点分为根节点&#xff0c;叶子结点&#xff08;没有分支的结点&#xff09; 以及分支结点 从上往下看&#xff0c;每个结点都有0个或多个后继 从下往上…

[读书日志]从零开始学习Chisel 第十二篇:Scala的抽象成员(敏捷硬件开发语言Chisel与数字系统设计)

9. Scala的抽象成员 9.1 抽象成员 Scala有4种抽象成员&#xff0c;分别是抽象val字段&#xff0c;抽象var字段&#xff0c;抽象方法和抽象类型。声明如下&#xff1a; scala> trait Abstract {| type T //抽象类型| def transform(x: T): T //抽象方法| val in…

未来十年:科技重塑生活的全景展望

在科技发展的浪潮中&#xff0c;过去十年我们目睹了智能手机、移动支付、共享经济等创新成果对生活的巨大改变。而未来十年&#xff0c;科技的步伐将迈得更大、更快&#xff0c;它将全方位地重塑人们的生活&#xff0c;从日常出行、健康管理到工作模式、社交互动&#xff0c;每…

面试之《web安全问题》

1. csrf攻击 &#xff08;Cross-site request forgery) 跨站请求伪造。利用用户的cookie&#xff0c;伪造用户操作接口。 案例 用户登陆了a网站&#xff0c;cookie已经生成。用户打开了钓鱼网站b&#xff0c;黑客在b网站中调用了a网站的接口&#xff0c;就可以用用户在a网站中的…

C++实现设计模式---抽象工厂模式 (Abstract Factory)

抽象工厂模式 (Abstract Factory) 抽象工厂模式 是一种创建型设计模式&#xff0c;提供一个接口&#xff0c;用于创建一组相关或互相依赖的对象&#xff0c;而无需指定它们的具体类。 意图 提供一个创建一组相关对象的接口&#xff0c;而无需指定它们的具体类。解决产品对象之…

Linux 音视频入门到实战专栏(音频篇)基于alsa api的音频播放/录制流程

文章目录 一、简介1.1、音频播放流程1.2、音频录制流程 二、播放音频示例三、录制音频示例 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; &#x1f4e2;本篇将介绍如何调用alsa api来进行音频数据的播放和录制。 一、简介 1.1、音频播放流…

开发指南090-使用python做微服务

平台的后台涉及到业务部分的使用java开发&#xff0c;基于springcloud。 涉及到大数据、AI、网页爬虫等领域的使用python开发。 使用python开发微服务过程如下: 1、读取bootstrap.yaml配置 def read_yaml(file): 读取配置文件 with open(file, r, encodingutf-8) as…

Mac远程控制电脑Windows怎么弄?

‌在Mac上远程控制Windows电脑通常需要借助专门的远程控制软件。本文将为您推荐一款操作简单、功能实用的远程控制软件&#xff0c;帮助您轻松实现Mac远程控制电脑Windows&#xff0c;提升工作效率&#xff0c;享受便捷操作。 远程看看软件是一款操作简单、界面美观的远程控制软…