当前位置: 首页 > news >正文

C++设计模式——Template Method模板方法模式

一,模板方法模式的定义

模板方法模式是一种行为型设计模式,它先定义了一个算法的大致框架,然后将算法的具体实现步骤分解到多个子类中。

模板方法模式为算法设计了一个抽象的模板,算法的具体代码细节由子类来实现,从而使算法在整体上结构稳定,但是又能被灵活修改和扩展。

模板方法模式在现实生活中的抽象实例:

美食烹饪:烹饪包含很多步骤,包括选食材、切菜、煮熟等,但是每道菜的食材和烹饪时间会不同,此时可以将烹饪的通用步骤抽象为模板方法,具体细节由不同的菜来决定。

游戏开发:游戏中的角色有移动、攻击、防御等共同行为,将共同行为抽象为模板方法,具体细节根据不同的游戏角色来单独实现。

车辆生产:车辆生产流程中有组装、装配、涂漆等共同步骤,将共同步骤抽象为模板方法,具体的生产步骤根据不同的车型来改变。

例如:打工人作息模板

二,模板方法模式的结构

模板方法模式主要包含以下组件:
1.抽象类(AbstractClass):
定了算法的大致框架,里面包含了一个模板方法(templateMethod)和多个基本操作方法(execute1, execute2),模板方法定义了算法的实现步骤,而算法的实现步骤由这些基本操作组成。抽象类只定义了模板方法和基本操作流程,不提供具体的代码实现。
2.具体类(ConcreteClass):
是抽象类的具体实现,里面实现了抽象类定义的基本操作方法(execute1, execute2),不同的具体类对基本操作方法的实现细节可能有差异。
组件之间的工作步骤如下:
1.在抽象类中定义一个模板方法(templateMethod),将模板方法作为算法的大致框架。
2.在抽象类中声明若干个基本操作方法(execute1, execute2),将这些方法在模板方法中按特定顺序调用,作为算法的执行流程。
3.在不同的具体类中,按照业务分别用代码实现基本操作方法。
对应UML类图:

三,模板方法模式代码样例

以下代码的结构和上述描述基本一致
#include <iostream>class AbstractClass {
public://模板方法void templateMethod() {//算法步骤execute1();execute2();}
protected://基本操作方法virtual void execute1() = 0;virtual void execute2() = 0;
};class ConcreteClassA : public AbstractClass {
protected:void execute1() override {std::cout << "ConcreteClassA: execute1 called" << std::endl;}void execute2() override {std::cout << "ConcreteClassA: execute2 called" << std::endl;}
};class ConcreteClassB : public AbstractClass {
protected:void execute1() override {std::cout << "ConcreteClassB: execute1 called" << std::endl;}void execute2() override {std::cout << "ConcreteClassB: execute2 called" << std::endl;}
};int main() {AbstractClass* classA = new ConcreteClassA();classA->templateMethod();AbstractClass* classB = new ConcreteClassB();classB->templateMethod();delete classA;delete classB;return 0;
}

运行结果:

ConcreteClassA: execute1 called
ConcreteClassA: execute2 called
ConcreteClassB: execute1 called
ConcreteClassB: execute2 called

四,模板方法模式的应用场景

软件框架开发:开发复杂的框架时先定义好基础流程,然后在子类中分别实现具体细节。

编译器开发:在编译器中先定义基本的步骤如词法分析、语法分析等,然后在子类中实现具体的解析步骤。

驱动程序开发:将程序的初始化、数据读写、通信等基础操作抽象为模板方法,然后根据不同的设备参数实现具体操作。

五,模板方法模式的优缺点

模板方法模式的优点:

使代码更加简洁,具体细节交给子类实现,避免了重复代码。

模板方法定义以后,后面只需要重点维护子类的代码实现,系统可扩展性和灵活性很强。

系统稳定性强,无论后续如何修改子类,算法的基本流程不变。

模板方法模式的缺点:

子类太多容易导致继承的过度滥用。

系统结构复杂,增加了代码维护难度。

如果有些基本操作没有提供默认的行为,可能导致功能出错。

六,代码实战

基于模板方法模式实现的模拟汽车生产

#include <iostream>class VehicleTemplate {
public:void buildVehicle() {assembleBody();installEngine();addWheels();std::cout<<"Vehicle is ready!\n";}virtual void assembleBody() = 0;virtual void installEngine() = 0;virtual void addWheels() = 0;
};class Car: public VehicleTemplate {
public:void assembleBody() override {std::cout<<"Assembling car body.\n";}void installEngine() override {std::cout<<"Installing car engine.\n";}void addWheels() override {std::cout<<"Adding 4 wheels to the car.\n ";}
};class Motorcycle: public VehicleTemplate {
public:void assembleBody() override {std::cout<<"Assembling motorcycle frame.\n";}void installEngine() override {std::cout<<"Installing motorcycle engine.\n";}void addWheels() override {std::cout<<"Adding 2 wheels to the motorcycle.\n ";}
};int main() {std::cout<<"Building a Car : \n";Car car;car.buildVehicle();std::cout<<"\nBuilding a Motorcycle : \n";Motorcycle motorcycle;motorcycle.buildVehicle();return 0;
}

运行结果:

Building a Car :
Assembling car body.
Installing car engine.
Adding 4 wheels to the car.
Vehicle is ready!Building a Motorcycle :
Assembling motorcycle frame.
Installing motorcycle engine.
Adding 2 wheels to the motorcycle.
Vehicle is ready!

七,参考阅读

https://www.geeksforgeeks.org/template-method-design-pattern-c-design-patterns/

https://sourcemaking.com/design_patterns/template_method

https://www.geeksforgeeks.org/template-method-design-pattern/

https://www.modernescpp.com/index.php/the-template-method/

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Renesa Version Board开发RT-Thread 之Client(WIFI)和上位机的数据传输
  • 如何使用小乌龟清除认证缓存、还原版本、定位及常用开发工具集成
  • 中间件解析漏洞
  • 领衔登榜!凯伦股份入选2024年度市级工业设计中心名单
  • 【弱监督时间动作定位】Probabilistic Vision-Language Representation for WSTAL 论文阅读
  • VBA进行excel坐标转换
  • JavaScript 条件分支语句if...else
  • 内核链表
  • Python作为客户端连接websocket
  • Webview Android性能优化
  • html+css网页设计 合十文化2个页面
  • adb remount Now reboot your device for settings to take effect
  • 中间件解析漏洞(附环境搭建教程)
  • 俄国留学生vs国内计算机本硕博
  • 基于STM32设计的智能安防系统(微信小程序)(218)
  • 分享一款快速APP功能测试工具
  • [Vue CLI 3] 配置解析之 css.extract
  • [译]如何构建服务器端web组件,为何要构建?
  • “大数据应用场景”之隔壁老王(连载四)
  • CAP 一致性协议及应用解析
  • Octave 入门
  • Sass 快速入门教程
  • TypeScript实现数据结构(一)栈,队列,链表
  • 关于Java中分层中遇到的一些问题
  • 基于axios的vue插件,让http请求更简单
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 前端攻城师
  • 前端之Sass/Scss实战笔记
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • $.ajax()参数及用法
  • (06)Hive——正则表达式
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (152)时序收敛--->(02)时序收敛二
  • (6)STL算法之转换
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (PADS学习)第二章:原理图绘制 第一部分
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (算法设计与分析)第一章算法概述-习题
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • (原)本想说脏话,奈何已放下
  • (转)Mysql的优化设置
  • (转)程序员疫苗:代码注入
  • (转)负载均衡,回话保持,cookie
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .NET 8.0 中有哪些新的变化?
  • .Net(C#)常用转换byte转uint32、byte转float等
  • .NET程序员迈向卓越的必由之路
  • .NET中两种OCR方式对比
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [1127]图形打印 sdutOJ
  • [2019.2.28]BZOJ4033 [HAOI2015]树上染色