[设计模式] --- 模板方法模式

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() 的实现是相同的。这样,每个传感器都可以自定义数据的采集和处理方式,同时使用了通用的算法流程,避免了重复的代码。

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

猜你喜欢

转载自blog.csdn.net/weixin_42445727/article/details/129864283