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() 和三个虚函数。
    • CSVDataProcessor 和 JSONDataProcessor 是具体类,分别实现了读取、处理和写入 CSV 和 JSON 数据的逻辑。
  • 继承关系:

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

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

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

  • 算法的框架:当你有一个算法的框架,但其中某些步骤需要在多个子类中实现时,模板方法模式非常适合。例如,处理不同格式的文件(如 CSV、XML、JSON)时,可以定义一个通用的处理流程。
  • 代码复用:当多个类有相似的操作步骤,但具体实现不同,可以使用模板方法来复用代码,减少重复。
  • 控制算法的执行顺序 :当你需要控制算法中某些步骤的执行顺序,而这些步骤的实现可能在子类中不同。
    个算法的框架,但其中某些步骤需要在多个子类中实现时,模板方法模式非常适合。例如,处理不同格式的文件(如 CSV、XML、JSON)时,可以定义一个通用的处理流程。
  • 代码复用:当多个类有相似的操作步骤,但具体实现不同,可以使用模板方法来复用代码,减少重复。
  • 控制算法的执行顺序:当你需要控制算法中某些步骤的执行顺序,而这些步骤的实现可能在子类中不同。
  • 框架设计:适用于设计框架,允许用户在特定的步骤中扩展或自定义行为,而不改变整体结构。
相关推荐
高晶7 小时前
CANopen 在 BMS 系统中的 C 语言实战指南
设计模式·程序员
weixin_307779137 小时前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
AI wins7 小时前
c++新增頭文件
c++
Shadow(⊙o⊙)7 小时前
仿muduo实现高并发服务器——事件就绪管理Channel.hpp
服务器·c++
by209997 小时前
哈希表——快速找到数据:冲突、删除与扩容的实现
数据结构·c++·哈希算法·散列表
博风8 小时前
13、设计模式应用举例:工厂方法模式:创建药品对象
设计模式·工厂方法模式
音草8 小时前
C++ 继承详解:从概念到菱形继承
c++
weixin_307779138 小时前
C++代码实现MATLAB中的spectralcluster函数功能
开发语言·c++·算法·matlab
xiaoye-duck9 小时前
《C++ 项目:手写大模型接入 SDK》Trae IDE 开发环境搭建与依赖管理
c++·ide·语言模型
沫璃染墨9 小时前
《Qt从零入门系列(十四):QThread多线程详解——从线程创建到客户端阻塞处理》
开发语言·c++·笔记·qt·ui·交互·线程