1 模板方法模式简介
模板方法模式适用于需要在多个类中实现类似算法或流程的场景,但每个类具体实现细节可能不同的情况下。模板方法模式通过将算法或流程的主要骨架定义在一个抽象类中,以及定义一些可变的方法,让具体实现交由子类完成。
2 模板方法模式示例代码
#include <iostream>
#include <vector>
// 定义排序算法抽象类
class SortAlgorithm {
public:
virtual ~SortAlgorithm() {
}
// 模板方法
void Sort(std::vector<int>& arr) {
DoSort(arr);
Print(arr);
}
protected:
// 定义具体实现方法
virtual void DoSort(std::vector<int>& arr) = 0;
// 定义可变的方法,子类可以自己实现
virtual void Print(const std::vector<int>& arr) {
std::cout << "Sorted array: ";
for (auto i : arr) {
std::cout << i << " ";
}
std::cout << std::endl;
}
};
// 定义具体的排序算法类,实现 DoSort 方法
class BubbleSort : public SortAlgorithm {
protected:
virtual void DoSort(std::vector<int>& arr) {
int n = arr.size();
for (int i = 0; i < n - 1; ++i) {
for (int j = 0; j < n - i - 1; ++j) {
if (arr[j] > arr[j+1]) {
std::swap(arr[j], arr[j+1]);
}
}
}
}
};
// 定义具体的排序算法类,实现 DoSort 方法
class QuickSort : public SortAlgorithm {
protected:
virtual void DoSort(std::vector<int>& arr) {
QuickSortHelper(arr, 0, arr.size()-1);
}
private:
void QuickSortHelper(std::vector<int>& arr, int left, int right) {
if (left >= right) return;
int pivot = arr[left];
int i = left + 1;
int j = right;
while (i <= j) {
while (i <= j && arr[i] < pivot) ++i;
while (i <= j && arr[j] > pivot) --j;
if (i <= j) {
std::swap(arr[i], arr[j]);
++i;
--j;
}
}
std::swap(arr[left], arr[j]);
QuickSortHelper(arr, left, j-1);
QuickSortHelper(arr, j+1, right);
}
};
int main() {
std::vector<int> arr = {
3, 1, 4, 1, 5, 9, 2, 6, 5, 3};
BubbleSort bubble_sort;
bubble_sort.Sort(arr);
std::vector<int> arr2 = {
3, 1, 4, 1, 5, 9, 2, 6, 5, 3};
QuickSort quick_sort;
quick_sort.Sort(arr2);
return 0;
}
定义了一个排序算法的抽象类 SortAlgorithm,其中包含一个模板方法 Sort(),该方法定义了排序算法的主要骨架,并调用了一个叫做 Print() 的可变方法,该方法的默认实现输出排序后的结果。子类只需要实现具体的排序算法,即 DoSort() 方法,就可以通过调用 Sort() 方法来完成排序,并且可以自定义 Print() 方法的实现来满足不同的需求。
在示例代码中,我们定义了 BubbleSort 和 QuickSort 两个具体的排序算法类,它们分别继承 SortAlgorithm 类,并实现了 DoSort() 方法。在 main() 函数中,我们分别创建了 BubbleSort 和 QuickSort 的实例,并调用它们的 Sort() 方法完成排序。
可以看到,通过使用模板方法模式,我们可以将排序算法的主要骨架和具体实现分离开来,使得我们可以方便地在不同的子类中实现具体的排序算法,并且可以在抽象类中定义一些可变的方法,使得子类可以根据需要自定义实现,从而更好地满足不同的需求。
3 多传感器场景模板方法模式代码示例
假设我们有多个传感器,每个传感器都可以采集数据并进行处理,最终将结果输出。使用模板方法模式可以将这些传感器的数据处理过程抽象出来,并定义一个通用的算法流程,同时允许每个传感器自定义数据的采集和处理方式。
以下是一个基于模板方法模式的多传感器数据处理示例代码:
#include <iostream>
#include <vector>
// 抽象传感器类
class Sensor {
public:
virtual ~Sensor() {
}
virtual void collectData() = 0;
virtual void processData() = 0;
virtual void outputResult() = 0;
// 模板方法,定义通用的算法流程
void process() {
collectData();
processData();
outputResult();
}
};
// 传感器 A
class SensorA : public Sensor {
public:
void collectData() override {
std::cout << "SensorA: Collecting data..." << std::endl;
// 采集数据的具体实现
}
void processData() override {
std::cout << "SensorA: Processing data..." << std::endl;
// 处理数据的具体实现
}
void outputResult() override {
std::cout << "SensorA: Outputting result..." << std::endl;
// 输出结果的具体实现
}
};
// 传感器 B
class SensorB : public Sensor {
public:
void collectData() override {
std::cout << "SensorB: Collecting data..." << std::endl;
// 采集数据的具体实现
}
void processData() override {
std::cout << "SensorB: Processing data..." << std::endl;
// 处理数据的具体实现
}
void outputResult() override {
std::cout << "SensorB: Outputting result..." << std::endl;
// 输出结果的具体实现
}
};
int main() {
std::vector<Sensor*> sensors = {
new SensorA(), new SensorB()};
for (auto sensor : sensors) {
sensor->process(); // 调用模板方法
std::cout << std::endl;
}
for (auto sensor : sensors) {
delete sensor;
}
return 0;
}
在这个示例中,我们首先定义了一个抽象的传感器类 Sensor,其中包含三个纯虚函数 collectData()、processData() 和 outputResult(),分别用于采集数据、处理数据和输出结果。接下来,我们定义了两个具体的传感器类 SensorA 和 SensorB,分别继承了 Sensor 类,并实现了相应的虚函数。
在 main() 函数中,我们定义了一个包含多个传感器指针的 vector,并将 SensorA 和 SensorB 的实例添加到 vector 中。然后,我们遍历这个 vector,并依次调用每个传感器的 process() 方法,即通用的算法流程,这个方法内部调用了 collectData()、processData() 和 outputResult() 三个虚函数,其中 collectData() 和 processData() 的具体实现由每个传感器自己定义,而 outputResult() 的实现是相同的。这样,每个传感器都可以自定义数据的采集和处理方式,同时使用了通用的算法流程,避免了重复的代码。
总的来说,模板方法模式适用于以下场景:
在一个算法中,有一些步骤是相同的,而另一些步骤是可变的,需要在子类中进行具体实现。
需要将具体实现细节从算法中抽象出来,让算法更加简洁。
多个类具有相同的算法流程,但每个类的实现细节不同。
在多传感器数据处理的场景中,使用模板方法模式可以将每个传感器的数据处理过程抽象出来,并定义一个通用的算法流程,同时允许每个传感器自定义数据的采集和处理方式,减少了代码冗余,并提高了代码的可读性和可维护性。