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

简介: [设计模式] --- 模板方法模式

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

总的来说,模板方法模式适用于以下场景:

在一个算法中,有一些步骤是相同的,而另一些步骤是可变的,需要在子类中进行具体实现。

需要将具体实现细节从算法中抽象出来,让算法更加简洁。

多个类具有相同的算法流程,但每个类的实现细节不同。

在多传感器数据处理的场景中,使用模板方法模式可以将每个传感器的数据处理过程抽象出来,并定义一个通用的算法流程,同时允许每个传感器自定义数据的采集和处理方式,减少了代码冗余,并提高了代码的可读性和可维护性。


相关文章
|
6月前
|
设计模式 算法
二十三种设计模式全面解析-深入解析模板方法模式的奇妙世界
二十三种设计模式全面解析-深入解析模板方法模式的奇妙世界
|
设计模式 存储 算法
行为型设计模式02-模板方法模式
行为型设计模式02-模板方法模式
50 0
|
设计模式 算法
设计模式9 - 模板方法模式【Template Method Pattern】
设计模式9 - 模板方法模式【Template Method Pattern】
37 0
|
设计模式 算法 Java
设计模式~模板方法模式(Template method)-10
目录 (1)优点: (2)缺点: (3)使用场景: (4)注意事项: (5)应用实例: (6)Servlet Api &
57 0
|
2月前
|
设计模式 算法 Java
Java设计模式-模板方法模式(14)
Java设计模式-模板方法模式(14)
|
4月前
|
设计模式 JavaScript 算法
js设计模式【详解】—— 模板方法模式
js设计模式【详解】—— 模板方法模式
48 6
|
5月前
|
设计模式 算法 关系型数据库
设计模式第七讲-外观模式、适配器模式、模板方法模式详解
系统要求所有的数据库帮助类必须实现ISqlHelp接口,面向该接口编程,如SQLServerHelp类。 此时第三方提供了一个新的MySql的帮助类(假设是dll,不能修改),它的编程规范和ISqlHelp不兼容,这个时候就需要引入适配器类,使二者能相互兼容。
170 0
|
6月前
|
设计模式 算法 Java
Java 设计模式:深入模板方法模式的原理与应用
【4月更文挑战第27天】模板方法模式是一种行为设计模式,主要用于定义一个操作中的算法的框架,允许子类在不改变算法结构的情况下重定义算法的某些特定步骤。
60 1
|
6月前
|
设计模式 Go
[设计模式 Go实现] 行为型~模板方法模式
[设计模式 Go实现] 行为型~模板方法模式
|
6月前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式