设计模式——模板方法模式

devtools/2024/11/6 15:29:36/

基本概念

模板方法模式是一种行为设计模式, 它在超类(基类)中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。

该模式是对于面向过程编程的一种抽象,它定义了一个算法的骨架,将一些步骤的实现延迟到子类。子类在不改变算法结构的情况下,重新定义算法的某些步骤。
比如,做一道菜至少需要三步:

  1. 准备食材
  2. 烹饪
  3. 上菜

虽然不同菜品的烹饪方法和准备过程不同,但是不妨碍我们定义一个算法的“骨架”,包含这三个步骤,然后将烹饪过程放到具体的炒菜类去实现,这样无论是吵什么才,都可以亚勇相同的炒菜算法,只需要在子类中实现具体的炒菜步骤就行。模板方法模式提高了代码的可复用性,类似于模板编程。

基本结构

在原来的若干类的基础上,抽象出一个模板方法,定义一个模板抽象类,然后具体类继承自模板类,实现了模板类中定义的抽象方法,去完成算法中的特定步骤。

  • 模板类AbstractClass:由一个模板方法和若干个基本方法构成,模板方法定义了逻辑的骨架,按照顺序去调用包含的基本方法,基本方法同时是一些抽象方法,这些方法由子类去实现。基本方法还包含一些具体方法,他们是算法类的一部分但已经有默认实现,在具体子类可以继承或者重写。
  • 具体类ConcreteClass:继承自模板类,实现了模板类中定义的抽象方法,完成算法中特定步骤的具体实现。
class AbstractClass {/*** The template method defines the skeleton of an algorithm.*/public:void TemplateMethod() const {this->BaseOperation1();this->RequiredOperations1();this->BaseOperation2();this->Hook1();this->RequiredOperation2();this->BaseOperation3();this->Hook2();}/*** These operations already have implementations.*/protected:void BaseOperation1() const {std::cout << "AbstractClass says: I am doing the bulk of the work\n";}void BaseOperation2() const {std::cout << "AbstractClass says: But I let subclasses override some operations\n";}void BaseOperation3() const {std::cout << "AbstractClass says: But I am doing the bulk of the work anyway\n";}/*** These operations have to be implemented in subclasses.*/virtual void RequiredOperations1() const = 0;virtual void RequiredOperation2() const = 0;/*** These are "hooks." Subclasses may override them, but it's not mandatory* since the hooks already have default (but empty) implementation. Hooks* provide additional extension points in some crucial places of the* algorithm.*/virtual void Hook1() const {}virtual void Hook2() const {}
};
/*** Concrete classes have to implement all abstract operations of the base class.* They can also override some operations with a default implementation.*/
class ConcreteClass1 : public AbstractClass {protected:void RequiredOperations1() const override {std::cout << "ConcreteClass1 says: Implemented Operation1\n";}void RequiredOperation2() const override {std::cout << "ConcreteClass1 says: Implemented Operation2\n";}
};
/*** Usually, concrete classes override only a fraction of base class' operations.*/
class ConcreteClass2 : public AbstractClass {protected:void RequiredOperations1() const override {std::cout << "ConcreteClass2 says: Implemented Operation1\n";}void RequiredOperation2() const override {std::cout << "ConcreteClass2 says: Implemented Operation2\n";}void Hook1() const override {std::cout << "ConcreteClass2 says: Overridden Hook1\n";}
};
/*** The client code calls the template method to execute the algorithm. Client* code does not have to know the concrete class of an object it works with, as* long as it works with objects through the interface of their base class.*/
void ClientCode(AbstractClass *class_) {// ...class_->TemplateMethod();// ...
}int main() {std::cout << "Same client code can work with different subclasses:\n";ConcreteClass1 *concreteClass1 = new ConcreteClass1;ClientCode(concreteClass1);std::cout << "\n";std::cout << "Same client code can work with different subclasses:\n";ConcreteClass2 *concreteClass2 = new ConcreteClass2;ClientCode(concreteClass2);delete concreteClass1;delete concreteClass2;return 0;
}
Same client code can work with different subclasses:
AbstractClass says: I am doing the bulk of the work
ConcreteClass1 says: Implemented Operation1
AbstractClass says: But I let subclasses override some operations
ConcreteClass1 says: Implemented Operation2
AbstractClass says: But I am doing the bulk of the work anywaySame client code can work with different subclasses:
AbstractClass says: I am doing the bulk of the work
ConcreteClass2 says: Implemented Operation1
AbstractClass says: But I let subclasses override some operations
ConcreteClass2 says: Overridden Hook1
ConcreteClass2 says: Implemented Operation2
AbstractClass says: But I am doing the bulk of the work anyway

上述代码源自该C++ 模板方法模式讲解和代码示例,我们来分析一下这个代码的含义。

首先是定义了一个抽象类,定义了公有方法TemplateMethod,按照一定的顺序把所有的类方法都执行一遍。并提供了两个公有函数BaseOperation1BaseOperation2,然后在保护域中定义了四个虚函数,RequireOperation1RequireOperation2是纯虚函数,子类必须实现,还有两个Hook1Hook2是提供了默认的空操作,子类可以选择自己实现。

然后在客户端直接去调用公有方法TemplateMethod,不同的子类的实现方式略有区别,子类1只实现了必要的操作,而子类2还实现了Hook1,即模板方法模式在已有的算法骨架下支持一定的拓展。

综上所述,模板方法模式适用于程式固化的模块,抽象出一个算法“骨架”这样可以方便统一管理,也支持一定的拓展。


http://www.ppmy.cn/devtools/131797.html

相关文章

站大爷代理IP工具的验证功能介绍

在网络世界中&#xff0c;代理IP的稳定性和有效性至关重要。站大爷代理IP工具以其高效的验证机制&#xff0c;帮助确保每个代理IP都能精准地完成任务。以下是该工具验证功能的详细介绍&#xff0c;让您轻松掌握如何使用这些功能。 一、自定义验证网址 想象一下&#xff0c;您…

【日常问题排查小技巧-连载】

线上服务CPU飙高排查 先执行 top&#xff0c;找到CPU占用比较高的进程 id&#xff0c;&#xff08;比如 21448&#xff09; jstack 进程 id > show.txt&#xff08;jstack 21448 > show.txt&#xff09; 找到进程中CPU占用比较高的线程&#xff0c;线程 id 转换为 16 进…

Interpreter 解释器模式

1 意图 给定一个语言&#xff0c;定义它的文法的一种表示&#xff0c;并定义一个解释器&#xff0c;这个解释器使用该表示》解释语言中的句子。 2 结构 AbstactExpression 声明一个程序的解释操作&#xff0c;这个接口为抽象语法树中所有的结点所共享。TemminalExpression 实…

FileLink如何帮助医疗行业实现安全且高效的跨网文件交换

在当今数字化时代&#xff0c;医疗行业在快速发展的同时&#xff0c;也面临着数据安全和信息流转效率的双重挑战。患者的健康记录、影像数据、检查报告等大量敏感信息需要在不同医院、诊所、实验室和保险公司之间高效、迅速地传递。然而&#xff0c;传统的邮件、传真和纸质文件…

Python 面试题以及在Java的对应

你如何理解 Python 中的装饰器&#xff1f; 装饰器是Python中一个强大的功能&#xff0c;它允许用户在不修改原有函数代码的情况下&#xff0c;增加函数的额外功能。装饰器通过在函数定义之前使用符号应用&#xff0c;实际上是一个接受函数作为参数并返回新函数的高阶函数。装饰…

conda进行本地环境打包和转移使用

要将Conda环境打包以便传输&#xff0c;您可以使用conda-pack工具。这个工具不是Conda默认的一部分&#xff0c;因此您可能需要先安装它&#xff1a; conda install -c conda-forge conda-pack安装完成后&#xff0c;您可以按照以下步骤打包并传输您的Conda环境&#xff1a; …

在软件设计时,怎样寻找和确定对象,以及设计模式的作用

在软件设计过程中&#xff0c;寻找和确定合适的对象是一个关键步骤&#xff0c;它直接影响到系统的整体设计和实现。以下是一些常用的方法和思路来帮助开发者识别和确定对象&#xff0c;以及与之相关的设计方法和举例说明&#xff1a; 1. 寻找和确定对象的方法 1.1 需求分析 …

MySQL45讲 第十三讲 为什么表数据删掉一半,表文件大小不变?

文章目录 MySQL45讲 第十二讲 为什么表数据删掉一半&#xff0c;表文件大小不变&#xff1f;一、引言二、InnoDB 表数据存储方式三、数据删除流程及表空间未回收原因四、重建表以回收表空间五、Online 与 inplace 概念区别六、总结 MySQL45讲 第十二讲 为什么表数据删掉一半&am…