设计模式——策略模式

定义与概念

策略模式(Strategy Pattern)是一种行为设计模式。它定义了一系列算法,将每个算法都封装起来,并且使它们可以相互替换。此模式让算法的变化独立于使用算法的客户。

简单来说,就好比在一个角色扮演游戏中,角色的攻击行为可以有多种策略,如近战攻击、远程攻击、魔法攻击等。这些不同的攻击策略可以被封装成不同的类,并且可以在游戏运行过程中根据实际情况(如角色装备的武器、技能等)进行切换。

结构组成

  • 策略(Strategy)接口:
    这是所有具体策略类的共同接口,它定义了策略方法的签名。例如,在一个路径规划系统中,策略接口可能定义了一个findPath()方法,用于寻找从一个点到另一个点的路径。
  • 具体策略(Concrete Strategy)类:
    实现了策略接口,提供了具体的算法实现。在路径规划系统中,可能有 "最短路径策略" 类,它的findPath()方法会使用迪杰斯特拉算法来寻找最短路径;还有 "随机路径策略" 类,它的findPath()方法会随机生成一条可行路径。
  • 上下文(Context)类:
    它持有一个策略接口的引用,用于调用具体的策略方法。上下文类的主要职责是维护策略对象,并在需要时调用策略对象的方法。在游戏角色攻击的例子中,游戏角色类就是上下文类,它维护一个攻击策略对象的引用,当需要进行攻击时,就调用这个攻击策略对象的attack()方法。

工作原理

客户端(使用策略的代码)创建一个具体策略对象,并将其传递给上下文类。上下文类在执行相关操作时,通过其持有的策略接口引用调用具体策略对象的方法。

例如,在一个文本格式化系统中,有 "加粗格式策略" 和 "斜体格式策略" 等具体策略类。上下文类(文本格式化器)可以接收用户选择的具体格式策略对象,当用户要求格式化文本时,文本格式化器就调用当前策略对象的format()方法来对文本进行相应的格式化处理。

代码示例

首先是策略接口,以排序策略为例:

cpp 复制代码
class SortStrategy {
public:
    virtual void sort(int arr[], int size) = 0;
};

具体策略类 - 冒泡排序:

cpp 复制代码
class BubbleSortStrategy : public SortStrategy {
public:
    void sort(int arr[], int size) override {
        for (int i = 0; i < size - 1; ++i) {
            for (int j = 0; j < size - i - 1; ++j) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
};

具体策略类 - 快速排序:

cpp 复制代码
class QuickSortStrategy : public SortStrategy {
public:
    int partition(int arr[], int low, int high) {
        int pivot = arr[high];
        int i = (low - 1);
        for (int j = low; j <= high - 1; ++j) {
            if (arr[j] <= pivot) {
                i++;
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        int temp = arr[i + 1];
        arr[i + 1] = arr[high];
        arr[high] = temp;
        return (i + 1);
    }
    void sort(int arr[], int size) override {
        std::stack<int> stack;
        stack.push(0);
        stack.push(size - 1);
        while (!stack.empty()) {
            int high = stack.top();
            stack.pop();
            int low = stack.top();
            stack.pop();
            int p = partition(arr, low, high);
            if (p - 1 > low) {
                stack.push(low);
                stack.push(p - 1);
            }
            if (p + 1 < high) {
                stack.push(p + 1);
                stack.push(high);
            }
        }
    }
};

上下文类:

cpp 复制代码
class Sorter {
private:
    SortStrategy* strategy;
public:
    Sorter(SortStrategy* s) : strategy(s) {}
    void setStrategy(SortStrategy* s) {
        strategy = s;
    }
    void sort(int arr[], int size) {
        strategy->sort(arr, size);
    }
};

使用示例:

cpp 复制代码
int main() {
    int arr[] = {5, 4, 3, 2, 1};
    int size = sizeof(arr) / sizeof(arr[0]);
    BubbleSortStrategy bubbleSort;
    Sorter sorter(&bubbleSort);
    sorter.sort(arr, size);
    for (int i = 0; i < size; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
    QuickSortStrategy quickSort;
    sorter.setStrategy(&quickSort);
    sorter.sort(arr, size);
    for (int i = 0; i < size; ++i) {
        std::cout << arr[i] << " ";
    }
    return 0;
}

优点

  • 可替换性:
    可以方便地替换算法(策略)。在上述排序的例子中,如果发现一种新的更高效的排序算法,只需要创建一个新的具体策略类实现排序策略接口,然后在上下文中替换原来的策略即可,不需要修改上下文类的其他部分。
  • 可维护性和可扩展性:
    将不同的算法封装在各自的类中,使得代码结构清晰,易于维护和扩展。如果要修改某个排序算法的实现,只需要在对应的具体策略类中进行修改,不会影响到其他策略和上下文类的大部分代码。
  • 符合开闭原则:
    对扩展开放,对修改关闭。当需要添加新的策略时,只需要实现策略接口,创建新的具体策略类,而不需要修改已有的代码。

缺点

  • 增加类的数量:
    每一个策略都需要一个具体策略类来实现,当策略较多时,会导致类的数量增加,使得代码的复杂性提高。例如,在一个复杂的金融交易系统中,如果有大量的交易策略,会产生很多策略类文件。
  • 客户端需要了解策略:
    客户端需要知道有哪些策略可供选择,并且需要知道如何创建和使用这些策略。在一些复杂的系统中,这可能会增加客户端代码的复杂性,尤其是当策略的选择和使用条件比较复杂时。
相关推荐
workflower19 小时前
情境感知系统
人工智能·机器学习·设计模式·自然语言处理·机器人
咖啡八杯21 小时前
设计模式中的原则
设计模式·接口隔离原则·里氏替换原则·开闭原则·合成复用原则·单一职责原则
安冬的码畜日常1 天前
【工欲善其事】深入理解 Node.js 带并发上限的异步任务批量执行逻辑
javascript·设计模式·node.js·ai编程·异步编程·并发执行
AI大法师1 天前
一个机场如何被做成 IP 场景:宝可梦机场的设计方法总结
大数据·人工智能·设计模式·新媒体运营
晚安code2 天前
干掉成山的 if-else:工厂造、策略选,一文讲透两个模式的配合
后端·设计模式
workflower2 天前
从幻觉,到现实
人工智能·深度学习·机器学习·设计模式·机器人
电子科技圈2 天前
第二代无线平台历久弥新,赋能物联网创新迭代
人工智能·嵌入式硬件·mcu·物联网·设计模式·硬件架构·iot
choumin2 天前
创建型模式——工厂方法模式
c++·设计模式·工厂方法模式·创建型模式
choumin3 天前
创建型模式——原型模式
c++·设计模式·原型模式·创建型模式
37.2℃9953 天前
Claude Design哪个公司技术好
python·设计模式