重温设计模式--模板方法模式

server/2024/12/25 8:15:37/

文章目录

  • 一、模板方法模式概述
  • 二、模板方法模式UML图
  • 三、优点
    • 1代码复用性高
    • 2可维护性好
    • 3扩展性强
  • 四、缺点
  • 五、使用场景
  • 六、C++ 代码示例1
  • 七、 C++ 代码示例2

一、模板方法模式概述

定义:定义一个操作中的算法骨架,而降一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
定义:模板方法模式是一种行为设计模式。它在一个抽象类中定义了一个算法的骨架(模板方法),将一些步骤的实现延迟到子类中。模板方法定义了算法的步骤顺序,子类可以根据自身的需求重写其中的某些步骤,而整体算法的流程结构保持不变。

二、模板方法模式UML图

在这里插入图片描述

三、优点

1代码复用性高

在抽象类中定义的模板方法和一些通用步骤可以在多个子类中复用,避免了代码的重复编写。例如,在一个游戏开发中,游戏角色的移动和攻击行为可能有共同的流程结构,通过模板方法模式可以把这个共同的流程提取出来,不同类型的角色(如战士、法师)可以复用这个流程,只需要实现自己特定的移动和攻击方式即可。

2可维护性好

由于算法的结构在抽象类中已经定义好,当需要对整体算法流程进行修改时,只需要在抽象类中修改模板方法的实现,而不需要在每个具体子类中进行修改。比如,在一个文件读取处理的系统中,如果要改变文件读取后的处理流程顺序,只需要在抽象的文件处理类的模板方法中调整步骤顺序,而各个具体文件类型(如文本文件、二进制文件)的处理子类可以保持不变。

3扩展性强

可以很方便地通过创建新的子类来扩展系统功能。新的子类可以选择性地重写模板方法中的步骤,以实现新的行为。例如,在一个图形绘制系统中,已经有了绘制基本图形(如圆形、矩形)的类,当需要添加一种新的图形(如三角形)时,只需要创建一个新的子类,重写绘制图形的具体步骤,而整体的图形绘制流程(如打开画布、选择颜色、绘制图形、关闭画布)可以复用已有的模板方法。

四、缺点

可能会导致类的层次结构复杂:因为需要创建抽象类和多个子类来实现模板方法模式,所以如果设计不当,可能会导致类的层次结构过于复杂,增加代码的理解和维护难度。
不符合开闭原则的部分情况:虽然模板方法模式在一定程度上符合开闭原则(对扩展开放,对修改关闭),但如果要对模板方法本身进行修改,可能会影响到所有的子类。例如,在模板方法中增加或删除一个步骤,可能需要在所有子类中进行相应的调整。

五、使用场景

多个子类有共同的算法流程,但某些步骤的实现细节不同:比如在一个订单处理系统中,线上订单和线下订单的处理流程都包括接收订单、处理支付、安排发货等步骤,但线上订单和线下订单在处理支付和安排发货的具体方式上可能不同。
需要控制子类的扩展行为,保证算法结构的稳定性:例如在一个编译器的语法分析模块中,不同编程语言的语法分析都有一个基本的流程,如词法分析、语法树构建、语义检查等步骤。通过模板方法模式可以定义这个基本流程,让不同编程语言的语法分析子类在这个框架内进行扩展,同时保证整体的语法分析算法结构不变。

六、C++ 代码示例1

以下是一个简单的 C++ 代码示例,模拟一个游戏角色攻击的模板方法模式。假设有一个抽象的 GameCharacter 类,定义了游戏角色攻击的模板方法,还有两个具体的角色类 Warrior 和 Mage,它们分别重写了攻击的具体实现方式。

#include <iostream>
#include <string>// 抽象游戏角色类
class GameCharacter 
{
public:// 模板方法,定义了攻击的算法流程void attack(){std::cout << "The character is preparing to attack." << std::endl;performAttack();std::cout << "The character has finished the attack." << std::endl;}
protected:// 抽象方法,由子类实现具体的攻击方式virtual void performAttack() = 0;
};// 战士角色类
class Warrior : public GameCharacter
{
protected:void performAttack() override {std::cout << "1" << std::endl;std::cout << "2" << std::endl;std::cout << "The warrior swings his sword." << std::endl;}
};// 法师角色类
class Mage : public GameCharacter
{
protected:void performAttack() override {std::cout << "The mage casts a spell." << std::endl;std::cout << "888" << std::endl;std::cout << "777" << std::endl;}
};
int main() 
{Warrior warrior;Mage mage;std::cout << "Warrior's attack:" << std::endl;warrior.attack();std::cout << "Mage's attack:" << std::endl;mage.attack();char t;std::cin>>t;return 0;
}

在上述代码中:
首先定义了抽象类 GameCharacter,它有一个公共的方法 attack,这就是模板方法。在 attack 方法中,定义了攻击行为的算法流程,包括准备攻击、执行具体的攻击动作(通过调用纯虚函数 performAttack)和完成攻击。performAttack 函数是一个纯虚函数,需要在子类中实现。
然后定义了两个具体的子类 Warrior 和 Mage,它们都继承自 GameCharacter。在这两个子类中,分别重写了 performAttack 函数,实现了战士挥舞剑和法师释放法术的不同攻击方式。
在 main 函数中,创建了 Warrior 和 Mage 类型的对象,并分别调用它们的 attack 方法,这样就会按照模板方法中定义的流程执行攻击行为,每个角色会执行自己特有的攻击动作。

七、 C++ 代码示例2

#include<iostream>
using namespace std;//抽象类,
//在父类中定义操作的算法骨架,而具体的实现由子类完成
class resume
{
protected:virtual void setedu(){}virtual void setage(){}virtual void setexp(){}
public:void setinformation()//骨架{setedu();setage();setexp();}
};
//子类
class xiaoming:public resume
{void setedu(){cout<<"清华大学"<<endl;}//具体实现void setage(){cout<<"19岁"<<endl;}//具体实现
};
class xiaoli:public resume
{void setedu(){cout<<"北京大学"<<endl;}//具体实现void setage(){cout<<"10岁"<<endl;}//具体实现void setexp(){cout<<"腾讯科技"<<endl;}
};
int main()
{resume *s1 = new xiaoming();s1->setinformation();cout<<endl<<endl;resume *s2 = new xiaoli();s2->setinformation();char t;std::cin>>t;return 0;
}

http://www.ppmy.cn/server/152999.html

相关文章

首次接触结构安全自动化监测系统,价格高吗?后期维护?

人工检测是依靠目测检查或借助于便携式仪器测量得到的信息&#xff0c;但是随着整个行业的发展&#xff0c;传统的人工检测方法已经不能满足检测需求&#xff0c;从人工检测到自动化监测已是必然趋势。 a. 从检测方式看 人工检测需要耗费大量的精力&#xff0c;从摆放检测工具到…

MongoDB教程001:基本常用命令(数据库操作和集合操作)

1.1 案例需求 存放文章评论的数据存放到MongoDB中&#xff0c;数据结构参考如下&#xff1a; 数据库&#xff1a;【articledb】 专栏文章评论comment字段名称字段含义字段类型备注_id&#xff08;MongoDB自动生成&#xff09;IDObjectId或StringMongo的主键的字段articleId文…

读书笔记~管理修炼-缄默效应

缄默效应&#xff1a;学会正确批评下属 员工明明犯了错误&#xff0c;却不及时告知你&#xff0c;总是拖到最后一刻无法弥补时才不得不承认出了问题——你遇到过这样的问题吗&#xff1f; 这其实是缄默效应在发挥作用。 在职场中&#xff0c;即使再扁平化的环境&…

【docker】docker desktop 在windows上支持 host模式

针对以前的情况&#xff0c;对于 Windows 和 macOS 用户&#xff0c;是不能够使用host模式的。只能在linux上才能够使用 更新日志 docker desktop 在4.34.0版本&#xff0c;开始支持host模式。

完全二叉树的权值(蓝桥杯2019年试题G)

给定一棵包含N个节点的完全二叉树&#xff0c;树上的每个节点都有一个权值&#xff0c;按从上到小、从左到右的顺序依次是A1、A2……An,&#xff08;1&#xff0c;2&#xff0c;n为下标。&#xff09;如下图所示。 现在&#xff0c;小明要把相同深度的节点的权值加到一起&#…

最新高性能多目标优化算法:多目标麋鹿优化算法(MOEHO)求解LRMOP1-LRMOP6及工程应用---盘式制动器设计,提供完整MATLAB代码

一、麋鹿优化算法 麋鹿优化算法&#xff08;Elephant Herding Optimization&#xff0c;EHO&#xff09;是2024年提出的一种启发式优化算法&#xff0c;该算法的灵感来源于麋鹿群的繁殖过程&#xff0c;包括发情期和产犊期。在发情期&#xff0c;麋鹿群根据公麋鹿之间的争斗分…

理想很丰满的Ollama-OCR

最近看到不少关于 Ollama OCR 项目友好可用的文章&#xff0c;也来试试。 安装依赖 我的环境是 python 3.11&#xff0c;直接安装下面这个库即可。 pip install ollama-ocr参考&#xff1a;imanoop7/Ollama-OCR 项目介绍 Ollama OCR &#xff1a;一个强大的光学字符识别&am…

Hive SQL 之 `LATERAL VIEW EXPLODE` 的正确打开方式

一文彻底搞懂 LATERAL VIEW EXPLODE 1. 引言 在处理复杂数据结构&#xff08;如数组、映射&#xff09;时&#xff0c;Hive SQL 提供了强大的功能来简化查询和数据分析。其中&#xff0c;LATERAL VIEW 和 EXPLODE 是两个特别有用的关键字&#xff0c;它们可以帮助我们将复杂的…