模板方法模式的C++实现示例

核心思想

模板方法设计模式是一种行为设计模式,它定义了一个算法的框架,并将某些步骤的具体实现延迟到子类中。通过这种方式,模板方法模式允许子类在不改变算法结构的情况下重新定义算法的某些步骤。

模板方法模式的核心在于:

​1、定义一个算法的骨架:在父类中定义一个模板方法,该方法包含算法的步骤。

​2、延迟实现:将某些步骤的具体实现交给子类来完成。

使用场景

​固定流程,可变实现:当算法的整体流程是固定的,但某些步骤的具体实现可能不同时。

​代码复用:当多个类有相似的算法结构,但某些步骤的实现不同时,可以通过模板方法模式避免代码重复。

​框架设计:在框架设计中,模板方法模式常用于定义框架的核心流程,同时允许用户自定义某些步骤。

优点

​代码复用:将公共的算法逻辑放在父类中,避免重复代码。

​扩展性:子类可以灵活地重写某些步骤,而不影响算法的整体结构。

​控制流程:父类控制算法的流程,子类只负责实现细节。

缺点

​灵活性受限:由于算法的流程是固定的,子类只能改变某些步骤的实现,不能改变整体流程。

​继承的缺点:模板方法模式依赖于继承,如果子类过多,可能会导致类层次结构复杂。

示例代码

cpp 复制代码
#include <iostream>
#include <string>

// 抽象基类:定义模板方法
class DocumentProcessor {
public:
    // 模板方法:定义算法的骨架
    void processDocument() {
        openDocument();
        readDocument();
        if (needAnalyze()) {
            analyzeDocument();
        }
        saveDocument();
        closeDocument();
    }

    virtual ~DocumentProcessor() = default;

protected:
    // 具体步骤的默认实现
    virtual void openDocument() {
        std::cout << "Opening document..." << std::endl;
    }

    virtual void readDocument() {
        std::cout << "Reading document..." << std::endl;
    }

    virtual void analyzeDocument() {
        std::cout << "Analyzing document..." << std::endl;
    }

    virtual void saveDocument() {
        std::cout << "Saving document..." << std::endl;
    }

    virtual void closeDocument() {
        std::cout << "Closing document..." << std::endl;
    }

    // 钩子方法:子类可以重写以改变算法的行为
    virtual bool needAnalyze() {
        return true;
    }
};

// 具体子类:实现特定类型的文档处理
class PDFProcessor : public DocumentProcessor {
protected:
    void openDocument() override {
        std::cout << "Opening PDF document..." << std::endl;
    }

    void saveDocument() override {
        std::cout << "Saving PDF document..." << std::endl;
    }

    bool needAnalyze() override {
        return false;  // PDF 文档不需要分析
    }
};

// 具体子类:实现另一种类型的文档处理
class WordProcessor : public DocumentProcessor {
protected:
    void openDocument() override {
        std::cout << "Opening Word document..." << std::endl;
    }

    void analyzeDocument() override {
        std::cout << "Analyzing Word document for spelling errors..." << std::endl;
    }

    void saveDocument() override {
        std::cout << "Saving Word document..." << std::endl;
    }
};

int main() {
    // 处理 PDF 文档
    DocumentProcessor* pdfProcessor = new PDFProcessor();
    pdfProcessor->processDocument();
    delete pdfProcessor;

    std::cout << "------------------------" << std::endl;

    // 处理 Word 文档
    DocumentProcessor* wordProcessor = new WordProcessor();
    wordProcessor->processDocument();
    delete wordProcessor;

    return 0;
}

输出结果

bash 复制代码
Opening PDF document...
Reading document...
Saving PDF document...
Closing document...
------------------------
Opening Word document...
Reading document...
Analyzing Word document for spelling errors...
Saving Word document...
Closing document...

代码解析

DocumentProcessor 类

定义了模板方法 processDocument(),它包含了文档处理的固定流程。

提供了默认的步骤实现(如 openDocument()、readDocument() 等)。

提供了一个钩子方法 needAnalyze(),子类可以重写以改变算法的行为。

PDFProcessor 和 WordProcessor 类

继承自 DocumentProcessor,重写了某些步骤的具体实现。

PDFProcessor 禁用了分析步骤,而 WordProcessor 提供了特定的分析逻辑。

main 函数

分别使用 PDFProcessor 和 WordProcessor 处理文档,展示了模板方法模式的灵活性。

相关推荐
江华森8 小时前
exp01_Python_数据类型
开发语言·python
Sylvia-girl8 小时前
第八站:vector及其常用操作【上】
c++
希冀1238 小时前
【JavaScript】Javascript—JS进阶—Day03
开发语言·javascript·原型模式
AI人工智能+电脑小能手8 小时前
【大白话说Java面试题 第156题】【06_Spring篇】第16题:Spring 用到了哪些设计模式?
java·spring·设计模式·代理模式·工厂模式
gugucoding8 小时前
28. 【C语言】通用数据操作:`void *` 与类型无关编程
c语言·开发语言
曹牧8 小时前
XML 解析过程中遇到 `org.xml.sax.SAXParseException
java·开发语言
Sunsets_Red8 小时前
浅谈博弈论
c++·学习·编程·博弈论·信息学竞赛·巴巴博弈
光影少年8 小时前
RN 架构:JS层、原生桥接层、原生渲染层 通信原理
开发语言·javascript·架构
ALex_zry9 小时前
C++26 std::inplace_vector 详解:零堆分配的定容向量
开发语言·c++
许彰午9 小时前
77_Python数据清洗实战技巧
开发语言·python