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

(三)行为模式:11、模板模式(Template Pattern)(C++示例)

目录

1、模板模式含义

2、模板模式的UML图学习

3、模板模式的应用场景

4、模板模式的优缺点

5、C++实现的实例


1、模板模式含义

模板模式(Template Method Pattern)是一种行为设计模式,它定义了一个操作中的算法骨架,将某些步骤的具体实现延迟到子类中。

        模板模式使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤,从而实现代码复用和扩展性。

2、模板模式的UML图学习

  • 抽象基类(AblstractClass):负责规定好接口,让子类实现接口,并定义一个模板方法。模板方法是算法骨架,包含了调用基本操作的步骤。
  • 具体实现子类(ConcreteClass):实现抽象基类的抽象接口,即实现模板方法中的基本操作。

3、模板模式的应用场景

(1)存在一组相似的操作:当有一组操作拥有相同的算法结构,但某些步骤的实现细节各不相同时,可以使用模板模式来定义这些操作的通用部分,并将变化的部分留给子类去实现。

(2)需要代码复用和扩展性:模板模式通过定义算法骨架和延迟某些步骤的实现,使得代码更加灵活和可扩展。

4、模板模式的优缺点

(1)优点:

  • 封装了不变部分,扩展了可变部分:模板模式将算法的不变部分封装在抽象基类中,而将可变部分延迟到子类中实现,从而实现了代码的复用和扩展。
  • 提高了代码的可维护性:由于算法骨架在抽象基类中定义,因此当算法结构发生变化时,只需要修改抽象基类即可,而不需要修改每个具体实现子类。

(2)缺点

  • 增加了系统的复杂性:模板模式需要定义抽象基类和具体实现子类,以及它们之间的继承关系,这可能会增加系统的复杂性。
  • 可能导致子类过多:如果算法中有多个可变步骤,那么可能需要定义多个具体实现子类来覆盖这些步骤,从而导致子类数量过多。

5、C++实现的实例

以下是一个使用C++实现的模板模式示例,该示例模拟了一个咖啡冲泡过程,其中包含了冲泡咖啡的算法骨架和不同的冲泡步骤实现。

#include <iostream>  
  
// 抽象基类,定义模板方法和基本操作  
class CoffeeMaker {  
public:  
    virtual ~CoffeeMaker() {}  
  
    // 模板方法:冲泡咖啡的步骤  
    void brewCoffee() {  
        boilWater();  
        brew();  
        pourInCup();  
        if (customerWantsCondiments()) {  
            addCondiments();  
        }  
    }  
  
protected:  
    // 基本操作,留给子类实现  
    virtual void brew() = 0;  
    virtual void addCondiments() = 0;  
  
    // 可能不需要子类重写的辅助方法  
    void boilWater() {  
        std::cout << "Boiling water" << std::endl;  
    }  
    void pourInCup() {  
        std::cout << "Pouring into cup" << std::endl;  
    }  
  
    // 可能需要子类决定的策略方法  
    virtual bool customerWantsCondiments() {  
        return true;  
    }  
};  
  
// 具体子类:黑咖啡  
class BlackCoffee : public CoffeeMaker {  
protected:  
    void brew() override {  
        std::cout << "Brewing black coffee" << std::endl;  
    }  
    void addCondiments() override {  
        // 黑咖啡不加调料  
    }  
};  
  
// 具体子类:加糖加奶咖啡  
class SugarMilkCoffee : public CoffeeMaker {  
protected:  
    void brew() override {  
        std::cout << "Brewing coffee with sugar and milk" << std::endl;  
    }  
    void addCondiments() override {  
        std::cout << "Adding sugar and milk" << std::endl;  
    }  
    bool customerWantsCondiments() override {  
        return true; // 假设加糖加奶咖啡总是需要加调料  
    }  
};  
  
int main() {  
    CoffeeMaker* maker = new BlackCoffee();  
    maker->brewCoffee();  
    delete maker;  
    std::cout << "\n";  
  
    maker = new SugarMilkCoffee();  
    maker->brewCoffee();  
    delete maker;  
  
    return 0;  
}

在这个示例中,CoffeeMaker类是抽象基类,它定义了冲泡咖啡的基本步骤作为模板方法(brewCoffee),并声明了两个纯虚函数brewaddCondiments作为基本操作,让子类去实现。通过这种方式,我们可以复用通用的冲泡流程,同时允许子类灵活地改变某些步骤,符合模板方法模式的设计理念。


http://www.kler.cn/news/362969.html

相关文章:

  • docker容器无法连接宿主机mysql排查
  • 【目标检测论文解读复现NO.39】基于改进 YOLOv8 的轻量级复杂环境苹果叶片病害检测方法
  • AWD的复现
  • 100种算法【Python版】第4篇——回溯法
  • 实战华为AC6508无线控制器+华为无线AP上线配置(AirEngine5762S-12+AirEngine5760-10)+无线WIFI配置
  • 智和信通助力某大型服饰集团建设综合监控运维
  • 【系统分析师】-论文-论需求开发
  • 双目视觉三角测量C语言代码实现不使用OpenCV
  • R语言笔记(一)
  • 基于neo4j的糖尿病知识图谱数据
  • 深入浅出 Vue3 nextTick
  • 推荐一个开源非线性视频编辑器:Kdenlive
  • 在一台不能接入互联网的服务器(cenos7)安装DOCKER
  • 基于YOLOv8深度学习的无人机视角高精度太阳能电池板检测与分析系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分割
  • 成长的代价
  • Telephony Contact
  • 信息系统的分类
  • JavaScript进阶:手写代码挑战(一)
  • chat_gpt回答:python 复制xml文件
  • AI绘画教程分享:Stable Diffusion最新使用指南
  • 大括号块作用域的起源是什么?为什么整型数值用补码保存?char类型变量是存储为int类型大小吗?枚举为什么被当做整型?编程语言标识符为什么不能以数字开头?
  • Java最全面试题->Java基础面试题->JavaWeb面试题->Maven面试题
  • Cookie与Session详解与应用
  • LangGraph 源码分析 | 结构化输出
  • Umi UI报错:连接失败,请尝试重启dev服务
  • 从一个简单的计算问题,看国内几个大语言模型推理逻辑能力