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() 的实现是相同的。这样,每个传感器都可以自定义数据的采集和处理方式,同时使用了通用的算法流程,避免了重复的代码。
总的来说,模板方法模式适用于以下场景:
在一个算法中,有一些步骤是相同的,而另一些步骤是可变的,需要在子类中进行具体实现。
需要将具体实现细节从算法中抽象出来,让算法更加简洁。
多个类具有相同的算法流程,但每个类的实现细节不同。
在多传感器数据处理的场景中,使用模板方法模式可以将每个传感器的数据处理过程抽象出来,并定义一个通用的算法流程,同时允许每个传感器自定义数据的采集和处理方式,减少了代码冗余,并提高了代码的可读性和可维护性。