(三)行为模式:11、模板模式(Template Pattern)(C++示例)

ops/2024/10/30 4:35:39/

目录

1、模板模式含义

2、模板模式的UML图学习

3、模板模式的应用场景

4、模板模式的优缺点

5、C++实现的实例


1、模板模式含义

模板模式(Template Method Pattern)是一种行为设计模式,它定义了一个操作中的算法骨架,将某些步骤的具体实现延迟到子类中。

        模板模式使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤,从而实现代码复用和扩展性。

2、模板模式的UML图学习

  • 抽象基类(AblstractClass):负责规定好接口,让子类实现接口,并定义一个模板方法。模板方法是算法骨架,包含了调用基本操作的步骤。
  • 具体实现子类(ConcreteClass):实现抽象基类的抽象接口,即实现模板方法中的基本操作。

3、模板模式的应用场景

(1)存在一组相似的操作:当有一组操作拥有相同的算法结构,但某些步骤的实现细节各不相同时,可以使用模板模式来定义这些操作的通用部分,并将变化的部分留给子类去实现。

(2)需要代码复用和扩展性:模板模式通过定义算法骨架和延迟某些步骤的实现,使得代码更加灵活和可扩展。

4、模板模式的优缺点

(1)优点:

  • 封装了不变部分,扩展了可变部分:模板模式将算法的不变部分封装在抽象基类中,而将可变部分延迟到子类中实现,从而实现了代码的复用和扩展。
  • 提高了代码的可维护性:由于算法骨架在抽象基类中定义,因此当算法结构发生变化时,只需要修改抽象基类即可,而不需要修改每个具体实现子类。

(2)缺点

  • 增加了系统的复杂性:模板模式需要定义抽象基类和具体实现子类,以及它们之间的继承关系,这可能会增加系统的复杂性。
  • 可能导致子类过多:如果算法中有多个可变步骤,那么可能需要定义多个具体实现子类来覆盖这些步骤,从而导致子类数量过多。

5、C++实现的实例

以下是一个使用C++实现的模板模式示例,该示例模拟了一个咖啡冲泡过程,其中包含了冲泡咖啡的算法骨架和不同的冲泡步骤实现。

#include <iostream>  // 抽象基类,定义模板方法和基本操作  
class CoffeeMaker {  
public:  virtual ~CoffeeMaker() {}  // 模板方法:冲泡咖啡的步骤  void brewCoffee() {  boilWater();  brew();  pourInCup();  if (customerWantsCondiments()) {  addCondiments();  }  }  protected:  // 基本操作,留给子类实现  virtual void brew() = 0;  virtual void addCondiments() = 0;  // 可能不需要子类重写的辅助方法  void boilWater() {  std::cout << "Boiling water" << std::endl;  }  void pourInCup() {  std::cout << "Pouring into cup" << std::endl;  }  // 可能需要子类决定的策略方法  virtual bool customerWantsCondiments() {  return true;  }  
};  // 具体子类:黑咖啡  
class BlackCoffee : public CoffeeMaker {  
protected:  void brew() override {  std::cout << "Brewing black coffee" << std::endl;  }  void addCondiments() override {  // 黑咖啡不加调料  }  
};  // 具体子类:加糖加奶咖啡  
class SugarMilkCoffee : public CoffeeMaker {  
protected:  void brew() override {  std::cout << "Brewing coffee with sugar and milk" << std::endl;  }  void addCondiments() override {  std::cout << "Adding sugar and milk" << std::endl;  }  bool customerWantsCondiments() override {  return true; // 假设加糖加奶咖啡总是需要加调料  }  
};  int main() {  CoffeeMaker* maker = new BlackCoffee();  maker->brewCoffee();  delete maker;  std::cout << "\n";  maker = new SugarMilkCoffee();  maker->brewCoffee();  delete maker;  return 0;  
}

在这个示例中,CoffeeMaker类是抽象基类,它定义了冲泡咖啡的基本步骤作为模板方法(brewCoffee),并声明了两个纯虚函数brewaddCondiments作为基本操作,让子类去实现。通过这种方式,我们可以复用通用的冲泡流程,同时允许子类灵活地改变某些步骤,符合模板方法模式的设计理念。


http://www.ppmy.cn/ops/129490.html

相关文章

Cesium基础-(Entity)-(Corridor 走廊)

里边包含Vue、React框架代码详细步骤、以及代码详细解释 4、Corridor 走廊 以下是 CorridorGeometry 类的属性、方法和静态方法,以表格形式展示: 属性 属性名类型默认值描述positionsArray.定义走廊中心的坐标点数组。widthnumber走廊

基于Matlab 人脸识别技术

Matlab 人脸识别技术 算法流程&#xff1a; 本系统运用PCA算法来实现人脸特征提取&#xff0c;然后通过计算欧式距离来判别待识别测试人脸&#xff0c;本个系统框架图如下&#xff1a; 图&#xff1a; 人脸识别系统框架图 整个系统的流程是这样的&#xff0c;首先通过图像采…

pandas read_html 如何才能读取多网页表格?

read_html()可免去写爬虫的烦恼&#xff0c;自动帮你抓取静态网页中的表格。 这里分为三种情况&#xff1a; 单网页多个表格&#xff0c;read_html()可以直接爬取所有表格&#xff0c;并以dataframe形式保存在列表中。多网页不同url&#xff0c;通过传入翻页参数&#xff0c;…

stm32学习3

学习目录 一.点亮LED&#xff08;寄存器&#xff09;1.使用宏定义 一.点亮LED&#xff08;寄存器&#xff09; 1.使用宏定义 在官方的文件中定义了很多的宏定义来表示stm32中每个引脚&#xff0c;这样可以简便开发&#xff1b; 改进后的代码&#xff1a; #include "st…

RabbitMQ安装部署

安装Erlang 由于RabbitMQ是用Erlang语言编写的&#xff0c;所以在安装RabbitMQ之前需要安装Erlang 安装依赖 [rootpro-ex ~]yum install make gcc gcc-c build-essential openssl openssl-devel unixODBC unixODBC-devel kernel-devel m4 ncurses-devel设置Eralng的存储库 […

【ACM出版,EI稳定检索,九大高校联合举办, IEEE Fellow支持】2024年计算机视觉与艺术研讨会(CVA 2024)

在线投稿&#xff1a;学术会议-学术交流征稿-学术会议在线-艾思科蓝 2024年计算机视觉与艺术国际学术会议&#xff08;CVA 2024&#xff09;作为2024年人工智能、数字媒体技术与交互设计国际学术会议&#xff08;ICADI 2024)的分会。此次大会旨在汇聚全球在计算机视觉与艺术…

IBM刚刚发布了第三代Granite大型语言模型

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

numpy——数学运算

一、标量——矢量 import numpy as npa 3.14 b np.array([[9, 5], [2, 7]])print(a) print(b)# ---------- 四则运算 ---------- print(a b) # np.add print(a - b) # np.subtract print(a * b) # np.multiply print(a / b) # np.divide 二、矢量——矢量 import nump…