2023-7-7-第十三式模板方法模式

news2024/9/23 3:26:57


🍿*★,°*:.☆( ̄▽ ̄)/$:*.°★* 🍿

💥💥💥欢迎来到🤞汤姆🤞的csdn博文💥💥💥
💟💟喜欢的朋友可以关注一下,下次更新不迷路💟💟
😆😆😆私聊获取个人订阅号哦,欢迎订阅共同学习😆😆😆
💖💖💖💖可以加入大家庭群聊,一起学习天天有福利💖💖💖💖





🍬本文摘要

在这里插入图片描述

设计方法二十三式之模板方法模式


目录

  • 🍬本文摘要
  • 😉一、基础概念
  • 🐱‍🐉二、模板方法模式实现
  • 🎉三、模块之间的关系
  • 🐱‍🚀四、注意事项
  • 🎂五、使用场景
  • 🍳参考文献
  • 🧊文章总结



😉一、基础概念

模板方法模式(Template Method Pattern)是一种行为设计模式,它定义了一个操作中的算法骨架,将一些步骤延迟到子类中实现。在模板方法模式中,一个抽象类公开定义了执行它的方法的方式/顺序,而具体的实现则由其子类提供

该模式主要包含以下角色:

  1. 抽象类(Abstract Class):定义了一个模板方法,该方法定义了算法的骨架,其中某些步骤由子类来实现。
  2. 具体类(Concrete Class):实现了抽象类中的抽象方法,完成算法中具体的步骤。

模板方法模式的核心思想是通过将相同的算法步骤封装在父类中,从而避免代码重复,并将可变的部分留给子类进行具体实现。这样可以保证整个算法的一致性和稳定性,同时也能够灵活地扩展和修改特定的步骤。该模式常用于处理一类问题的多个变种情况,以及在框架设计中定义通用的流程控制结构。


🐱‍🐉二、模板方法模式实现

在C++中,模板方法模式可以使用类的继承和虚函数来实现。下面是一个简单的示例:

#include <iostream>

// 抽象类
class AbstractClass {
public:
    // 模板方法
    void templateMethod() {
        primitiveOperation1(); // 调用具体的步骤1
        primitiveOperation2(); // 调用具体的步骤2
    }

protected:
    // 抽象方法,由子类实现具体步骤1
    virtual void primitiveOperation1() = 0;

    // 抽象方法,由子类实现具体步骤2
    virtual void primitiveOperation2() = 0;
};

// 具体类A
class ConcreteClassA : public AbstractClass {
protected:
    void primitiveOperation1() override {
        std::cout << "ConcreteClassA: 执行步骤1" << std::endl;
    }

    void primitiveOperation2() override {
        std::cout << "ConcreteClassA: 执行步骤2" << std::endl;
    }
};

// 具体类B
class ConcreteClassB : public AbstractClass {
protected:
    void primitiveOperation1() override {
        std::cout << "ConcreteClassB: 执行步骤1" << std::endl;
    }

    void primitiveOperation2() override {
        std::cout << "ConcreteClassB: 执行步骤2" << std::endl;
    }
};

int main() {
    AbstractClass* objectA = new ConcreteClassA();
    objectA->templateMethod();

    AbstractClass* objectB = new ConcreteClassB();
    objectB->templateMethod();

    delete objectA;
    delete objectB;

    return 0;
}

在上述示例中,AbstractClass 是抽象类,定义了模板方法 templateMethod(),该方法是算法的骨架。它调用了两个纯虚函数 primitiveOperation1()primitiveOperation2(),这些函数由具体类来实现。

ConcreteClassAConcreteClassB 是两个具体类,分别继承了 AbstractClass 并实现了具体步骤。在 main() 函数中创建了两个对象,并调用了它们的模板方法。

输出结果:

ConcreteClassA: 执行步骤1
ConcreteClassA: 执行步骤2
ConcreteClassB: 执行步骤1
ConcreteClassB: 执行步骤2

从输出可以看出,模板方法在不同的具体类中执行了相同的算法骨架,但具体步骤的实现有所区别。这展示了模板方法模式的特点和优势。


🎉三、模块之间的关系

在模板方法模式中,主要涉及两个关键角色:抽象类和具体类。

  1. 抽象类(Abstract Class):抽象类是定义模板方法的地方。它包含了一个或多个抽象方法,这些方法由具体类来实现。抽象类也可以包含一些具体的方法,这些方法在模板方法中被调用,但也可以在具体类中进行重写。

  2. 具体类(Concrete Class):具体类是抽象类的子类,它实现了抽象类中的抽象方法。具体类提供了特定步骤的实现,以完成整个算法。每个具体类都可以有不同的实现方式,但遵循了模板方法定义的算法结构。

模块之间的关系如下:

  • 抽象类作为模板方法的定义者,定义了算法的骨架,其中包含一个或多个抽象方法。抽象类通过调用抽象方法来形成完整的算法流程。
  • 具体类继承抽象类,并实现了抽象方法。具体类负责提供具体步骤的实现,以完成整个算法。每个具体类可以根据自身的需求,提供不同的实现方式。

模板方法模式通过将通用算法骨架放在抽象类中,将可变的具体实现委托给具体类,实现了高内聚、低耦合的设计思想。这种设计模式提供了一种扩展和修改算法的方式,同时保持了整个算法的一致性。


🐱‍🚀四、注意事项

在使用模板方法模式时,有一些注意事项需要考虑:

  1. 设计良好的抽象类:抽象类应该定义一个合理的算法骨架,并确保在模板方法中调用的抽象方法都能被正确实现。抽象类应该提供一个稳定且可靠的模板方法,以免导致子类实现不一致或错误。

  2. 虚函数和纯虚函数的使用:抽象类中的抽象方法可以是虚函数或纯虚函数。使用虚函数允许在抽象类中提供默认的实现,而使用纯虚函数则要求子类必须提供自己的具体实现。

  3. 理解模板方法的作用范围:模板方法只适用于整个算法流程中相对固定的部分。如果某个步骤在不同的情况下具有不同的行为,那么可能需要将其分离成独立的策略模式或其他模式来处理。

  4. 避免过度复杂化的算法:模板方法应该保持简洁和易于理解。如果算法的步骤过多或过于复杂,可能会导致代码难以维护和理解。在这种情况下,考虑重构算法,将一些步骤分解成小块的方法,以提高可读性和可维护性。

  5. 考虑扩展性:模板方法模式应该具备良好的扩展性,使得子类可以轻松添加新的步骤或修改现有步骤。在设计时要留出适当的扩展点,并考虑到可能的变化需求。

总之,使用模板方法模式时要确保抽象类定义了正确的算法骨架,并且具体类实现了正确的步骤。关注代码的可读性、可维护性和扩展性,避免过度复杂化的算法。


🎂五、使用场景

模板方法模式适用于以下场景:

  1. 算法的整体结构相对稳定:如果算法的骨架在不同的实现中是相同的,但其中的某些步骤可能有所不同,那么可以使用模板方法模式。这样可以避免重复编写相同的代码,将公共部分抽象到抽象类中。

  2. 保持算法一致性:模板方法模式确保了算法的一致性,子类只需要实现自己特定的步骤,而无需关心算法的整个流程。这有助于提高代码的可维护性和可读性,并降低出错的风险。

  3. 多个相关类具有共同行为:如果存在多个具有相似行为的类,但其中某些步骤的实现会有所不同,可以使用模板方法模式来避免重复代码。通过在抽象类中定义通用的算法骨架,子类只需提供各自的实现。

  4. 需要增加新的步骤或修改现有步骤:模板方法模式能够方便地扩展或修改算法的步骤。通过添加新的具体类,可以添加新的步骤,或者通过重写已有的步骤来修改算法的行为。

  5. 使用钩子方法进行扩展:抽象类可以提供钩子方法(Hook Method),用于在算法的不同步骤中插入额外的行为。子类可以选择性地重写这些钩子方法,以实现自己的逻辑。

总之,模板方法模式适用于需要定义算法骨架且在具体实现中存在差异的情况。它提供了一种代码复用和扩展的方式,使得整个算法结构更加清晰、可维护和灵活。常见的应用场景包括框架设计、算法封装和工作流程管理等。


🍳参考文献

🧊文章总结

提示:这里对文章进行总结:

   本文讲了关于模板方法模式的知识。






更多好文推荐

🍸2021-4月Python 机器学习——中文新闻文本标题分类
🍹2021年4月-(计算机网络)小型校园网络模拟搭建,最全最准确版
🍺2022-10-31-基于用户的协同过滤推荐算法实现+MAE+RMSE
🍻2022-11-28-大数据可视化,特征维度大于50
🥂2023-3-9-一篇简短的文章把C++左右值关系讲的透透彻彻

上一篇
End
下一篇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/732667.html

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

相关文章

代码随想录算法训练营第60天/最后一天 | 84.柱状图中最大的矩形

今日任务 目录 84.柱状图中最大的矩形 - Hard 84.柱状图中最大的矩形 - Hard 题目链接&#xff1a;力扣-84. 柱状图中最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够…

Android之Handler分析与理解

Android中的Handler是一个用于处理消息和线程间通信的机制。它可以将Runnable对象或Message对象发送到特定的线程中进行处理。 使用Handler的主要目的是在不同的线程之间进行通信&#xff0c;特别是在后台线程中执行一些任务后&#xff0c;将结果发送到UI线程进行更新。 流程图…

pearsonr 报错:numpy.float64 can not be interpreted as an integer

【1】 模型求出pred&#xff0c;pearsonr(pred,true&#xff09; 出现以下报错&#xff1a; 【2】解释&#xff1a; 当在计算皮尔逊相关系数&#xff08;Pearson correlation coefficient&#xff09;时出现"numpy.float64 can not be interpreted as an integer"的…

7.7~7.8学习总结

StringBuider&#xff1a;线程不安全&#xff0c;效率高 StringBuffer&#xff1a;线程安全&#xff0c;效率低&#xff1b; 用法举例&#xff1a; class TWC {public static void main(String []args){StringBuilder sbnew StringBuilder("小麻子爱吃粑粑");Syst…

C语言学习(三十六)---文件操作

上节内容中&#xff0c;我们学习了练习了动态内存的练习题&#xff0c;并且学习了柔性数组的相关内容&#xff0c;大叫要好好掌握&#xff0c;今天&#xff0c;我们将学习文件操作的相关内容&#xff0c;这部分内容实际上很多&#xff0c;我们以点代面&#xff0c;好了&#xf…

windows已有mysql的情况下 mysql8 安装

安装前先停掉本地已有的mysql服务https://dev.mysql.com/downloads/mysql/ 下载mysql压缩包解压创建 my.init 文件 [mysqld] port 3307 basedirF:\mysql-8.0.33-winx64\mysql-8.0.33-winx64 datadirF:\mysql-8.0.33-winx64\mysql-8.0.33-winx64\data max_connections200 cha…

3.3.内存的学习,pinnedmemory,内存效率问题

目录 前言1. Memory总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习精简 CUDA 教程-内存模型&#xff0c;pinned memory&am…

2023.7.08

#include "widget.h"void Widget::my_slot() {if((edit1->text()"admin")&&(edit2->text()"123456")){qDebug()<<"登陆成功";emit jump();close();}else{qDebug()<<"登陆失败";} }void Widget::b…

OSPFv2基础02_工作原理

目录 1.OSPF接口状态 2.OSPF邻居状态 2.1 OSPF邻居状态类型 2.2 广播网络OSPF邻接关系建立 3.Router ID&#xff08;路由器ID&#xff09;选举 4.DR和BDR选举 4.1 为什么引入DR和BDR&#xff1f; 4.2 DR和BDR的作用 4.3 DR和BDR选举过程 4.4 DR和BDR选举原则 5.OSPF路…

基于单片机指纹考勤系统的设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;利用指纹采集模块存储打卡信息&#xff1b;12864显示当前考勤信息&#xff0c;时间 &#xff1b;如果迟到 语音播报 您已迟到&#xff1b;按键进行注册指纹、删除指纹、设置当前时间和签到时间、查询打卡等&#xff1b;具有掉电保存…

【YOLOv7调整detect.py】1.调整检测框粗细,2.设定标签颜色,3.只显示与标签数目相同的检测结果

目录 1. 调整检测框粗细2. 设定标签颜色3. 只显示与标签数目相同的检测结果 1. 调整检测框粗细 在detect.py中按住CtrlF检索line_thickness定位过去&#xff0c;在129行左右&#xff0c;更改line_thickness的大小即可&#xff0c;例如改为line_thickness3 2. 设定标签颜色 在…

Spring核心 and 创建使用

Spring核心 and 创建使用 文章目录 Spring核心 and 创建使用一、Spring的定义1.1什么是IoC1.1.1 理解控制反转&#xff08;IoC&#xff09;1.1.2 控制反转式程序开发 1.2 使用Spring IoC核心功能2.1 DI的概念说明 二、Spring的创建和使用2.1 创建一个Maven项目2.2 添加Spring框…

解决在jupyter notebook中找不到pip安装后的库

解决在jupyter notebook中找不到已安装的库

Todo-List案例版本二

(160条消息) Todo-List案例版本一_bubbleJessica的博客-CSDN博客 引入了localStorage&#xff0c;让案例更加完善 src/App.vue <template><div id"root"><div class"todo-container"><div class"todo-wrap"><MyHe…

pycharm 打开终端,安装第三方程序

鼠标移动到左下角 弹出列表&#xff0c;选择终端&#xff0c;当然也可以用快捷键唤出&#xff0c; 可以输入命令进行第三方库的安装

Redis实战案例14-分布式锁的基本原理、不同实现方法对比以及基于Redis进行实现思路

1. 分布式锁基本原理 基于数据库的分布式锁&#xff1a;这种方式使用数据库的特性来实现分布式锁。具体流程如下&#xff1a; 获取锁&#xff1a;当一个节点需要获得锁时&#xff0c;它尝试在数据库中插入一个特定的唯一键值&#xff08;如唯一约束的主键&#xff09;&#xff…

vue 进阶---动态组件 插槽 自定义指令

目录 动态组件 如何实现动态组件渲染 使用 keep-alive 保持状态 keep-alive 对应的生命周期函数 keep-alive 的 include 属性和exclude属性 插槽 插槽的基础用法 具名插槽 作用域插槽 自定义指令 自定义指令的分类 私有自定义指令 全局自定义指令 了解 eslint 插件…

mysql 单表查询练习

mysql 单表查询练习 创建数据表代码 CREATE TABLE emp (empno int(4) NOT NULL,ename varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,job varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,mgr int(4) NULL DEFAU…

附件上传报java.lang.RuntimeException: java.nio.file.NoSuchFileException的问题

1、报错信息 java.lang.RuntimeException: java.lang.RuntimeException: java.nio.file.NoSuchFileException: /tmp/undertow.5113172416389412561.31101/undertow1781128540461109448upload 2、原因 Java项目以java -jar命令启动后&#xff0c;进行文件上传的操作&#xff0c…

android 测试google pay

1、到GooglePlay后台创建商品&#xff0c;需要注意的是要创建商品必须先发布一个带有Billing库的aab到GooglePlay&#xff08;测试渠道即可&#xff09; 2、获取并配置好商品id之后&#xff0c;将测试用的aab发布到内部测试&#xff0c;并添加测试人员的邮箱。 3、通过连接分享…