跳转到内容

策略模式

来自代码酷

模板:Note

概述[编辑 | 编辑源代码]

策略模式是一种行为型设计模式,允许在运行时选择算法的具体实现。其核心思想是将算法族(一组相关算法)封装为独立的类,使它们可以相互替换,且算法的变化不影响使用算法的客户端。

模板:Definition 定义一个算法族,将每个算法封装起来,并使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。

设计原则[编辑 | 编辑源代码]

策略模式体现了以下设计原则:

  • 开闭原则:无需修改客户端代码即可扩展新算法
  • 单一职责原则:每个算法类只负责一个具体策略
  • 组合优于继承:通过对象组合而非继承来实现行为变化

结构[编辑 | 编辑源代码]

classDiagram class Context { -strategy: Strategy +setStrategy(Strategy) +executeStrategy() } class Strategy { <<interface>> +execute() } class ConcreteStrategyA { +execute() } class ConcreteStrategyB { +execute() } Context o--> Strategy Strategy <|-- ConcreteStrategyA Strategy <|-- ConcreteStrategyB

关键角色说明:

  • Context:持有策略引用的环境类
  • Strategy:策略接口(抽象策略)
  • ConcreteStrategy:具体策略实现

代码示例[编辑 | 编辑源代码]

以下示例展示排序策略的可互换实现:

Java 实现[编辑 | 编辑源代码]

// 策略接口
interface SortStrategy {
    void sort(int[] data);
}

// 具体策略A:冒泡排序
class BubbleSort implements SortStrategy {
    @Override
    public void sort(int[] data) {
        System.out.println("使用冒泡排序");
        // 实际排序实现...
    }
}

// 具体策略B:快速排序
class QuickSort implements SortStrategy {
    @Override
    public void sort(int[] data) {
        System.out.println("使用快速排序");
        // 实际排序实现...
    }
}

// 上下文类
class Sorter {
    private SortStrategy strategy;

    public void setStrategy(SortStrategy strategy) {
        this.strategy = strategy;
    }

    public void executeSort(int[] data) {
        strategy.sort(data);
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        Sorter sorter = new Sorter();
        int[] data = {5, 2, 9, 1, 5};

        sorter.setStrategy(new BubbleSort());
        sorter.executeSort(data.clone());

        sorter.setStrategy(new QuickSort());
        sorter.executeSort(data.clone());
    }
}

模板:Output

Python 实现[编辑 | 编辑源代码]

from abc import ABC, abstractmethod

# 策略接口
class SortStrategy(ABC):
    @abstractmethod
    def sort(self, data):
        pass

# 具体策略
class BubbleSort(SortStrategy):
    def sort(self, data):
        print("使用冒泡排序")
        # 实际排序实现...

class QuickSort(SortStrategy):
    def sort(self, data):
        print("使用快速排序")
        # 实际排序实现...

# 上下文
class Sorter:
    def __init__(self, strategy: SortStrategy):
        self._strategy = strategy

    def sort(self, data):
        self._strategy.sort(data)

# 客户端
if __name__ == "__main__":
    data = [5, 2, 9, 1, 5]
    sorter = Sorter(BubbleSort())
    sorter.sort(data.copy())

    sorter = Sorter(QuickSort())
    sorter.sort(data.copy())

应用场景[编辑 | 编辑源代码]

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

  • 需要动态切换算法时
  • 有多个条件语句选择不同算法变体时
  • 算法需要独立于使用它的客户端时

真实案例[编辑 | 编辑源代码]

电商系统折扣策略

classDiagram class CheckoutService { -discountStrategy: DiscountStrategy +applyDiscount(order) } class DiscountStrategy { <<interface>> +calculateDiscount(order) } class ChristmasDiscount { +calculateDiscount(order) } class BlackFridayDiscount { +calculateDiscount(order) } CheckoutService o--> DiscountStrategy DiscountStrategy <|-- ChristmasDiscount DiscountStrategy <|-- BlackFridayDiscount

优缺点[编辑 | 编辑源代码]

模板:Pros

模板:Cons

相关模式[编辑 | 编辑源代码]

  • 状态模式:策略模式类似,但策略模式中的策略是静态配置的,而状态模式中的状态会随着上下文自动变化
  • 工厂模式:常与策略模式结合使用来创建具体策略对象
  • 命令模式:将操作封装为对象,策略模式则是封装算法

数学表达[编辑 | 编辑源代码]

策略模式可以形式化表示为: {ContextStrategysConcreteStrategies, sStrategyexecute()={s1.execute()if strategy=s1s2.execute()if strategy=s2...sn.execute()if strategy=sn

其中:

  • Context 依赖于抽象策略 Strategy
  • 具体策略 s1,s2,...,sn 实现策略接口

进阶思考[编辑 | 编辑源代码]

  • 如何结合依赖注入框架管理策略?
  • 策略模式与Lambda表达式的关系?
  • 如何避免策略膨胀问题?