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

模板方法模式

模板方法模式

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

引入"模板方法"设计模式的定义(实现意图):定义一个操作中的算法的骨架(稳定部分),而将一些步骤延迟到子类中去实现(父类中定义虚函数,让子类实现/重写这个虚函数)从而达到在整体稳定的情况下产生一些变化的目的。

逐步重构并引入模板方法模式

假设我们需要处理不同格式的数据(如 CSV 和 JSON)。最初的实现可能是重复的代码。逐步重构的过程如下:

初始实现

为每种数据格式编写独立的处理逻辑:

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

// CSV 数据处理
void processCSV() {
    std::cout << "Reading data from CSV file." << std::endl;
    std::cout << "Processing CSV data." << std::endl;
    std::cout << "Writing data to CSV file." << std::endl;
}

// JSON 数据处理
void processJSON() {
    std::cout << "Reading data from JSON file." << std::endl;
    std::cout << "Processing JSON data." << std::endl;
    std::cout << "Writing data to JSON file." << std::endl;
}

int main() {
    processCSV();
    processJSON();
    return 0;
}
提取共性并引入模板方法模式

识别出读取、处理和写入的共性步骤,并创建一个抽象类 DataProcessor,定义模板方法 process() 和虚函数:

cpp 复制代码
class DataProcessor {
public:
    void process() {
        readData();
        processData();
        writeData();
    }

protected:
    virtual void readData() = 0;
    virtual void processData() = 0;
    virtual void writeData() = 0;
};
实现具体类

为每种数据格式实现具体类,重写虚函数:

cpp 复制代码
class CSVDataProcessor : public DataProcessor {
private:
    void readData() override {
        std::cout << "Reading data from CSV file." << std::endl;
    }

    void processData() override {
        std::cout << "Processing CSV data." << std::endl;
    }

    void writeData() override {
        std::cout << "Writing data to CSV file." << std::endl;
    }
};

class JSONDataProcessor : public DataProcessor {
private:
    void readData() override {
        std::cout << "Reading data from JSON file." << std::endl;
    }

    void processData() override {
        std::cout << "Processing JSON data." << std::endl;
    }

    void writeData() override {
        std::cout << "Writing data to JSON file." << std::endl;
    }
};

完整代码示例

以下是完整的实现代码:

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

// 抽象类
class DataProcessor {
public:
    void process() {
        readData();
        processData();
        writeData();
    }

protected:
    virtual void readData() = 0;    // 读取数据
    virtual void processData() = 0; // 处理数据
    virtual void writeData() = 0;   // 写入数据
};

// 具体类:CSV 数据处理
class CSVDataProcessor : public DataProcessor {
private:
    void readData() override {
        std::cout << "Reading data from CSV file." << std::endl;
    }

    void processData() override {
        std::cout << "Processing CSV data." << std::endl;
    }

    void writeData() override {
        std::cout << "Writing data to CSV file." << std::endl;
    }
};

// 具体类:JSON 数据处理
class JSONDataProcessor : public DataProcessor {
private:
    void readData() override {
        std::cout << "Reading data from JSON file." << std::endl;
    }

    void processData() override {
        std::cout << "Processing JSON data." << std::endl;
    }

    void writeData() override {
        std::cout << "Writing data to JSON file." << std::endl;
    }
};

// 示例用法
int main() {
    DataProcessor* processor;

    // 处理 CSV 数据
    processor = new CSVDataProcessor();
    processor->process();
    delete processor;

    // 处理 JSON 数据
    processor = new JSONDataProcessor();
    processor->process();
    delete processor;

    return 0;
}

模板方法模式的 UML 图

模板方法模式的 UML 类图通常包含一个抽象类和多个具体类。以下是模板方法模式的 UML 图示例:

UML 图详细介绍
    • DataProcessor 是抽象类,定义了模板方法 process() 和三个虚函数。
    • CSVDataProcessorJSONDataProcessor 是具体类,分别实现了读取、处理和写入 CSV 和 JSON 数据的逻辑。
  • 继承关系

    • 继承关系通过带实线箭头表示,显示了 CSVDataProcessorJSONDataProcessor 继承自 DataProcessor
  • 方法可见性

    • +:表示公共方法,可以被外部访问,比如 process()
    • -:表示私有方法,只能在类内部访问,比如 readData()processData()writeData()
    • #:表示保护方法,子类可以访问,但外部无法访问。

模板方法模式适用于以下场景

  • 算法的框架:当你有一个算法的框架,但其中某些步骤需要在多个子类中实现时,模板方法模式非常适合。例如,处理不同格式的文件(如 CSV、XML、JSON)时,可以定义一个通用的处理流程。
  • 代码复用:当多个类有相似的操作步骤,但具体实现不同,可以使用模板方法来复用代码,减少重复。
  • 控制算法的执行顺序 :当你需要控制算法中某些步骤的执行顺序,而这些步骤的实现可能在子类中不同。
    个算法的框架,但其中某些步骤需要在多个子类中实现时,模板方法模式非常适合。例如,处理不同格式的文件(如 CSV、XML、JSON)时,可以定义一个通用的处理流程。
  • 代码复用:当多个类有相似的操作步骤,但具体实现不同,可以使用模板方法来复用代码,减少重复。
  • 控制算法的执行顺序:当你需要控制算法中某些步骤的执行顺序,而这些步骤的实现可能在子类中不同。
  • 框架设计:适用于设计框架,允许用户在特定的步骤中扩展或自定义行为,而不改变整体结构。
相关推荐
Dream it possible!2 小时前
LeetCode 面试经典 150_二叉搜索树_二叉搜索树中第 K 小的元素(86_230_C++_中等)
c++·leetcode·面试
y***54883 小时前
PHP框架设计模式
设计模式
Bona Sun4 小时前
单片机手搓掌上游戏机(十四)—pico运行fc模拟器之电路连接
c语言·c++·单片机·游戏机
oioihoii4 小时前
性能提升11.4%!C++ Vector的reserve()方法让我大吃一惊
开发语言·c++
小狗爱吃黄桃罐头4 小时前
《C++ Primer Plus》模板类 Template 课本实验
c++
口袋物联6 小时前
设计模式之适配器模式在 C 语言中的应用(含 Linux 内核实例)
c语言·设计模式·适配器模式
MobotStone6 小时前
大数据:我们是否在犯一个大错误?
设计模式·架构
码力码力我爱你7 小时前
Harmony OS C++实战
开发语言·c++
Vect__7 小时前
别再只懂 C++98!C++11 这7个核心特性,直接拉开你与普通开发者的差距
c++
想唱rap7 小时前
C++ map和set
linux·运维·服务器·开发语言·c++·算法