admin管理员组

文章数量:1531497

【c++设计模式22】行为模式7:策略模式(Strategy Pattern)

  • 二、适用场景
  • 三、过程
  • 四、策略模式类图
  • 五、C++示例代码
  • 六、使用注意事项
  • 六、具体的demo
  • 六、使用注意事项

原创作者:郑同学的笔记
原创地址:https://zhengjunxue.blog.csdn/article/details/132920283
qq技术交流群:921273910

类型序号设计模式描述
行为模式1责任链模式
(Chain of Responsibility)
将这些处理者连成一条链。 链上的每个处理者都有一个成员变量来保存下一个处理者。
2命令模式
(Command Pattern)
它将请求封装为一个对象,从而使得可以用不同的请求对客户端进行参数化或将请求放入队列中
3迭代器模式
(Iterator Pattern)
它提供了一种顺序访问聚合对象中各个元素的方法,而不暴露其内部表示。
4中介者模式
(Mediator Pattern)
通过中介对象进行通信,从而降低了对象之间的耦合性。
5备忘录模式
(Memento Pattern)
当需要保存和恢复对象的状态时,可以使用备忘录模式。
6观察者模式
(Observer Pattern)
当一个对象的状态发生改变时,所有依赖它的对象都会自动收到通知并更新。
7策略模式
(Strategy Pattern)
定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。客户端代码在运行时选择所需的算法。
8状态模式
(State Pattern
是在一个类的内部会有多种状态的变化,因为状态变化从而导致其行为的改变,在类的外部看上去这个类就像是自身发生了改变一样。
9模板方法模式
(Template Method Pattern)
定义了算法的基本骨架,而具体方法则由子类提供具体实现。
10访问者模式
(Visitor Pattern)
访问者定义了针对不同元素的操作方法,而元素则是被访问者访问的对象。
# 一、定义 策略模式是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。客户端代码在运行时选择所需的算法。

二、适用场景

策略模式适用于以下情况:

  • 当一个系统需要多个相似但不完全相同的算法,并且需要动态地在运行时选择其中一个算法时,可以使用策略模式。这样可以避免大量的 if-else 或 switch-case 结构。
  • 当一个类中有许多行为或操作,可以将这些行为或操作抽象成不同的策略类,以简化类的设计和维护。

三、过程

策略模式的过程包括以下几个角色:

抽象策略(Strategy):定义了策略的接口,具体策略类需要实现该接口。
具体策略(ConcreteStrategy):实现了抽象策略的具体算法StrategyA ,StrategyB。
环境(Client):持有一个策略对象的引用,用于执行具体的算法。

四、策略模式类图

策略模式中的若干个策略对象相互之间是完全独立的, 它们不知道其他对象的存在。当我们想使用对象中各种不同的算法变体,并希望能够在运行的时候切换这些算法时,可以选择使用策略模式来处理这个问题。

五、C++示例代码

以下是一个使用策略模式的示例代码,我们将使用策略模式实现一个简单的排序算法,包括冒泡排序和快速排序:

#include <iostream>
#include <string>
using namespace std;

// 抽象策略接口,定义算法的共同语义
class Strategy {
public:
    virtual void doSomething(string input) = 0;
};

// 具体策略类A,实现算法的特定实现
class StrategyA : public Strategy {
public:
    void doSomething(string input) override {
        cout << "StrategyA: " << input << endl;
    }
};

// 具体策略类B,实现算法的特定实现
class StrategyB : public Strategy {
public:
    void doSomething(string input) override {
        cout << "StrategyB: " << input << endl;
    }
};

// 客户端代码,使用策略对象来执行算法
class Client {
public:
    void executeStrategy(Strategy* strategy, string input) {
        strategy->doSomething(input);
    }
};

int main() {
    Client client;
    StrategyA* strategyA = new StrategyA();  // 选择具体策略类A的实例作为参数传递给客户端代码
    StrategyB* strategyB = new StrategyB();  // 选择具体策略类B的实例作为参数传递给客户端代码
    client.executeStrategy(strategyA, "input1");  // 执行具体策略类A的算法操作
    client.executeStrategy(strategyB, "input2");  // 执行具体策略类B的算法操作
    delete strategyA;  // 释放内存资源
    delete strategyB;  // 释放内存资源
    return 0;
}

输出

六、使用注意事项

使用策略模式时,需要将算法和环境类解耦,确保算法的变化不会影响到客户端。
在添加新的策略时,只需要增加具体策略类,而无需修改原有的代码。
注意选择合适的策略,不同的策略适用于不同的问题场景。
策略模式要求客户端了解各个具体策略的区别,选择合适的策略进行使用。

六、具体的demo

#include <iostream>
#include <vector>

// 抽象策略
class SortStrategy {
public:
    virtual void sort(std::vector<int>& data) = 0;
};

// 具体策略A - 冒泡排序
class BubbleSort : public SortStrategy {
public:
    void sort(std::vector<int>& data) override {
        int n = data.size();
        for (int i = 0; i < n - 1; ++i) {
            for (int j = 0; j < n - i - 1; ++j) {
                if (data[j] > data[j + 1]) {
                    std::swap(data[j], data[j + 1]);
                }
            }
        }
    }
};

// 具体策略B - 快速排序
class QuickSort : public SortStrategy {
private:
    void quickSort(std::vector<int>& data, int low, int high) {
        if (low < high) {
            int pivot = partition(data, low, high);
            quickSort(data, low, pivot - 1);
            quickSort(data, pivot + 1, high);
        }
    }

    int partition(std::vector<int>& data, int low, int high) {
        int pivot = data[high];
        int i = low - 1;
        for (int j = low; j <= high - 1; ++j) {
            if (data[j] < pivot) {
                ++i;
                std::swap(data[i], data[j]);
            }
        }
        std::swap(data[i + 1], data[high]);
        return i + 1;
    }

public:
    void sort(std::vector<int>& data) override {
        quickSort(data, 0, data.size() - 1);
    }
};

// 环境类
class Context {
private:
    SortStrategy* strategy;

public:
    Context(SortStrategy* strategy) : strategy(strategy) {}

    void setStrategy(SortStrategy* strategy) {
        this->strategy = strategy;
    }

    void execute(std::vector<int>& data) {
        strategy->sort(data);
    }
};

int main() {
    // 创建环境类和具体策略对象
    Context context(new BubbleSort);
    std::vector<int> data = {4, 2, 7, 1, 5};

    // 使用冒泡排序策略进行排序
    context.execute(data);
    std::cout << "Bubble Sort: ";
    for (int num : data) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 切换到快速排序策略进行排序
    context.setStrategy(new QuickSort);
    context.execute(data);
    std::cout << "Quick Sort: ";
    for (int num : data) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出

在上述示例中,我们定义了抽象策略 SortStrategy,其中包含一个排序算法的接口 sort。

具体策略A BubbleSort 和具体策略B QuickSort 分别实现了抽象策略接口,并实现了自己的排序算法。

环境类 Context 持有一个策略对象的引用,通过调用策略对象的排序方法来执行具体的算法。

在 main 函数中,我们创建了一个环境类对象和一个初始数据数组。首先使用冒泡排序策略进行排序,并输出结果;然后切换到快速排序策略进行排序,并再次输出结果。

六、使用注意事项

使用策略模式时,需要将算法和环境类解耦,确保算法的变化不会影响到客户端。
在添加新的策略时,只需要增加具体策略类,而无需修改原有的代码。
注意选择合适的策略,不同的策略适用于不同的问题场景。
策略模式要求客户端了解各个具体策略的区别,选择合适的策略进行使用。

本文标签: 模式策略PatternStrategy