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

实战设计模式之模板方法模式

概述

        模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类为这些步骤提供具体的实现。模板方法模式非常适合用于那些有固定流程或步骤,但在不同情况下需要稍微调整或扩展每个步骤的场景。

        咖啡制作是现实生活中运用模板方法模式的一个典型例子:虽然不同种类的咖啡(比如:浓缩咖啡、拿铁、卡布奇诺等)有不同的制作细节,但它们共享一个通用的流程框架。这个框架包括一些基本步骤,比如:加热水、冲泡咖啡、倒入杯中、添加调料。通过使用模板方法模式,我们可以定义这个通用的流程,并允许具体的咖啡类型自定义某些步骤。

基本原理

        模板方法模式的基本原理是:通过一个抽象类来定义一个操作中算法的骨架(即一系列步骤),但将一些步骤的具体实现延迟到子类中。这样,子类可以通过重写这些步骤的方法来定制特定于该子类的行为,同时保持算法的整体流程不变。

        模板方法模式主要由以下三个核心组件构成。

        1、抽象类。定义了模板方法,该方法给出了算法的骨架,通常包含了一系列调用“原始操作”的方法。另外,抽象类还可能提供了一些默认实现的方法。

        2、原始操作。这些是在抽象类中声明的抽象方法,它们代表了算法的不同步骤,需要由具体的子类提供实现。

        3、具体类。继承自抽象类,并提供了抽象方法的具体实现。这允许不同的具体类根据自己的需求,对算法的部分步骤进行定制。

        基于上面的核心组件,模板方法模式的实现主要有以下四个步骤。

        1、创建抽象类。定义一个抽象类,在其中声明一个或多个模板方法。模板方法是一个具体方法,它定义了算法的框架,并调用了若干个抽象方法或其他基本操作。在抽象类中声明所有需要子类实现的抽象方法,

        2、定义抽象方法。确定哪些步骤需要子类提供具体实现,并在抽象类中将其声明为抽象方法。这些抽象方法,即原始操作,代表了算法的不同步骤。

        3、提供默认实现。如果某些步骤对于所有子类来说都是相同的,或者可以有一个合理的默认实现,则可以在抽象类中提供这些步骤的默认实现。子类可以根据需要,选择是否覆盖这些方法。

        4、创建具体类。创建具体类,继承自抽象类,并实现所有必要的抽象方法。

实战代码

        在下面的实战代码中,我们使用模板方法模式模拟了咖啡制作的过程。

        首先,我们定义了一个抽象类CCoffee,它包含了制作咖啡的算法骨架MakeCoffee。该方法依次调用了四个步骤:加热水(BoilWater)、冲泡咖啡粉(BrewCoffeeGrinds)、倒入杯中(PourInCup)、添加调料(AddCondiments)。在这四个步骤中,冲泡咖啡粉BrewCoffeeGrinds和添加调料AddCondiments被声明为纯虚函数,要求由具体的子类提供实现,而BoilWater和PourInCup提供了默认实现。

        接下来,我们定义了具体类CEspresso和CLatte。它们分别实现了浓缩咖啡和拿铁咖啡特有的冲泡和添加调料的方法,从而定制了各自的制作流程。

        最后,在main函数中,通过基类指针创建了CEspresso和CLatte对象,并调用了它们的MakeCoffee方法。

#include <iostream>
#include <string>using namespace std;// 抽象类,定义了制作咖啡的基本步骤
class CCoffee
{
public:// 模板方法,定义了制作咖啡的算法骨架void MakeCoffee(){BoilWater();BrewCoffeeGrinds();PourInCup();AddCondiments();}protected:// 基本步骤,由子类实现具体逻辑virtual void BrewCoffeeGrinds() = 0;virtual void AddCondiments() = 0;// 默认实现,可以被子类覆盖virtual void BoilWater(){cout << "Boiling water" << endl;}virtual void PourInCup(){cout << "Pouring into cup" << endl;}
};// 具体类:浓缩咖啡
class CEspresso : public CCoffee
{
protected:void BrewCoffeeGrinds() override{cout << "Dripping coffee through filter for espresso" << endl;}void AddCondiments() override{cout << "No condiments for espresso" << endl;}
};// 具体类:拿铁咖啡
class CLatte : public CCoffee
{
protected:void BrewCoffeeGrinds() override{cout << "Steeping coffee for latte" << endl;}void AddCondiments() override{cout << "Adding steamed milk and cinnamon" << endl;}
};int main()
{CCoffee* pEspresso = new CEspresso();pEspresso->MakeCoffee();cout << endl;CCoffee* pLatte = new CLatte();pLatte->MakeCoffee();delete pEspresso;delete pLatte;return 0;
}

总结

        模板方法模式通过将通用的算法框架放在抽象类中,使得这些通用步骤可以在所有子类之间共享。这减少了重复代码,并促进了代码复用。由于算法的整体结构由抽象类控制,确保了所有具体实现都遵循相同的流程。这样可以保证行为的一致性,尤其是在需要严格遵守某种操作顺序的情况下。虽然算法的整体结构是固定的,但允许子类重写某些步骤以满足特定需求,提供了极大的灵活性。

        虽然子类可以重写某些步骤,但它们不能改变算法的基本结构或顺序。这意味着,如果需要完全不同的算法流程,则无法仅通过重写现有方法来实现,必须重新设计整个结构。另外,对于简单的应用场景,引入模板方法模式可能会使设计变得过于复杂。特别是当只有少数几个步骤需要定制化时,使用这种模式可能显得过度设计。

http://www.lqws.cn/news/186931.html

相关文章:

  • Go 中的 Map 与字符处理指南
  • 如何使用Webhook触发器,在 ONLYOFFICE 协作空间构建智能工作流
  • C++中的概念(Concepts)
  • 自然语言处理的发展
  • 数字孪生恰似企业的“智能军师”,精准助力决策
  • 【python基础知识】 *args, **kwargs介绍
  • 一篇文章实现Android图片拼接并保存至相册
  • 深入了解linux系统—— 进程池
  • Redis哨兵模式
  • CSS 性能优化
  • 微信小程序动态效果实战指南:从悬浮云朵到丝滑列表加载
  • 密码学基础——SM4算法
  • spring重试机制
  • 一种全新的非对称加密算法
  • 从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
  • 金融系统渗透测试
  • 交易所系统攻坚:高并发撮合引擎与合规化金融架构设计
  • pe文件结构(TLS)
  • 字节推出统一多模态模型 BAGEL,GPT-4o 级的图像生成能力直接开源了!
  • Linux(线程控制)
  • python八股文算法:三数之和
  • 实践提炼,EtherNet/IP转PROFINET网关实现乳企数字化工厂增效
  • 正则持续学习呀
  • B站的视频怎么下载下来——Best Video下载器
  • Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
  • 2025年- H73-Lc181--22.括号生成(回溯,组合)--Java版
  • Git仓库的创建
  • 2025/6/6—halcon知识点总结
  • c++ set与multiset的介绍
  • SOC-ESP32S3部分:32-LVGL显示框架