模板方法模式
- 模板方法模式
- 逐步重构并引入模板方法模式
- 初始实现
- 提取共性并引入模板方法模式
- 实现具体类
- 完整代码示例
- 模板方法模式的 UML 图
- UML 图详细介绍
- 模板方法模式适用于以下场景
模板方法模式
模板方法模式是一种行为设计模式,它定义了一个算法的骨架,而将一些步骤延迟到子类中。通过这种方式,模板方法允许子类在不改变算法结构的情况下重新定义算法的某些特定步骤。
引入“模板方法”设计模式的定义(实现意图):定义一个操作中的算法的骨架(稳定部分),而将一些步骤延迟到子类中去实现(父类中定义虚函数,让子类实现/重写这个虚函数)从而达到在整体稳定的情况下产生一些变化的目的。
逐步重构并引入模板方法模式
假设我们需要处理不同格式的数据(如 CSV 和 JSON)。最初的实现可能是重复的代码。逐步重构的过程如下:
初始实现
为每种数据格式编写独立的处理逻辑:
#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()
和虚函数:
class DataProcessor {
public:
void process() {
readData();
processData();
writeData();
}
protected:
virtual void readData() = 0;
virtual void processData() = 0;
virtual void writeData() = 0;
};
实现具体类
为每种数据格式实现具体类,重写虚函数:
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;
}
};
完整代码示例
以下是完整的实现代码:
#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)时,可以定义一个通用的处理流程。 - 代码复用:当多个类有相似的操作步骤,但具体实现不同,可以使用模板方法来复用代码,减少重复。
- 控制算法的执行顺序:当你需要控制算法中某些步骤的执行顺序,而这些步骤的实现可能在子类中不同。
- 框架设计:适用于设计框架,允许用户在特定的步骤中扩展或自定义行为,而不改变整体结构。