当前位置: 首页 > news >正文

策略模式_行为型_GOF23


策略模式

策略模式(Strategy Pattern)是一种行为型设计模式,核心思想是将一组算法封装成独立对象,使它们可以相互替换,从而让算法的变化独立于使用它的客户端。这类似于游戏中的技能切换——玩家根据战况选择不同技能(火球术、冰箭术),而角色的攻击逻辑无需修改。


一、通俗理解

以商场促销为例:

  1. 传统方式:用 if-else 判断促销类型(满减、折扣、积分),导致代码臃肿且难以扩展新促销策略。
  2. 策略模式
    • 促销策略接口:定义统一的优惠计算接口(如 calculate())。
    • 具体策略类:满减策略、折扣策略等各自实现算法。
    • 订单上下文:持有当前策略对象,调用时动态执行对应算法。
      当新增“双倍积分”促销时,只需添加新策略类,无需修改现有代码。

二、模式结构
  1. 抽象策略(Strategy):定义算法的公共接口(如 execute())。
  2. 具体策略(ConcreteStrategy):实现具体算法(如加法、折扣)。
  3. 上下文(Context):维护策略对象引用,提供切换和执行接口。

三、适用场景
  1. 动态算法切换:如支付方式(微信、支付宝)、排序算法(快排、归并)。
  2. 消除条件分支:替代大量 if-elseswitch-case 语句。
  3. 算法复用与扩展:需要独立管理多种算法变体时。

四、优缺点分析
优点缺点
1. 灵活扩展:新增策略无需修改上下文1. 类数量膨胀:每个策略需独立类
2. 消除条件判断:代码更简洁易维护2. 客户端需感知策略存在
3. 符合开闭原则:算法与使用解耦3. 性能开销:频繁切换可能影响效率

五、代码实现
1. C++ 示例(计算器策略)
#include <iostream>  

// 抽象策略:运算接口  
class Strategy {  
public:  
    virtual int execute(int a, int b) = 0;  
    virtual ~Strategy() = default;  
};  

// 具体策略:加法  
class AddStrategy : public Strategy {  
public:  
    int execute(int a, int b) override {  
        return a + b;  
    }  
};  

// 上下文:计算器  
class Calculator {  
    Strategy* strategy;  
public:  
    void setStrategy(Strategy* s) { strategy = s; }  
    int calculate(int a, int b) {  
        return strategy->execute(a, b);  
    }  
};  

int main() {  
    Calculator calc;  
    calc.setStrategy(new AddStrategy());  
    std::cout << "10 + 5 = " << calc.calculate(10, 5) << std::endl;  // 输出15  
    // 切换策略示例:calc.setStrategy(new SubtractStrategy());  
    return 0;  
}  

解析

  • 通过 setStrategy() 动态更换加减乘除算法。

2. Python 示例(促销策略)
from abc import ABC, abstractmethod  

class PromotionStrategy(ABC):  
    @abstractmethod  
    def calculate(self, price: float) -> float:  
        pass  

class FullReductionStrategy(PromotionStrategy):  # 满减策略  
    def calculate(self, price):  
        return price - 20 if price >= 100 else price  

class DiscountStrategy(PromotionStrategy):       # 折扣策略  
    def calculate(self, price):  
        return price * 0.8  

class Order:  
    def __init__(self, strategy: PromotionStrategy):  
        self.strategy = strategy  
    def checkout(self, price):  
        return self.strategy.calculate(price)  

# 客户端  
order = Order(FullReductionStrategy())  
print(f"满减后价格:{order.checkout(150)}")  # 输出130.0  

特点

  • Python支持鸭子类型,无需严格接口继承。

3. Java 示例(支付策略 + 工厂模式)
// 策略接口  
interface PaymentStrategy {  
    void pay(double amount);  
}  

// 具体策略:微信支付  
class WechatPay implements PaymentStrategy {  
    public void pay(double amount) {  
        System.out.printf("微信支付:%.2f元\n", amount);  
    }  
}  

// 策略工厂(管理实例)  
class PaymentFactory {  
    private static final Map<String, PaymentStrategy> strategies = new HashMap<>();  
    static {  
        strategies.put("wechat", new WechatPay());  
        strategies.put("alipay", new Alipay());  
    }  
    public static PaymentStrategy getStrategy(String key) {  
        return strategies.getOrDefault(key, new DefaultPay());  
    }  
}  

// 上下文  
class ShoppingCart {  
    private PaymentStrategy strategy;  
    public void setStrategy(String key) {  
        this.strategy = PaymentFactory.getStrategy(key);  
    }  
    public void checkout(double amount) {  
        strategy.pay(amount);  
    }  
}  

// 测试  
ShoppingCart cart = new ShoppingCart();  
cart.setStrategy("wechat");  
cart.checkout(99.9);  // 输出:微信支付:99.90元  

优化点

  • 工厂模式集中管理策略实例,避免重复创建。

六、总结与扩展

策略模式通过算法封装动态切换实现了高扩展性,特别适合以下场景:

  1. 电商促销:不同优惠规则独立管理。
  2. 游戏技能系统:角色动态切换攻击策略。
  3. 数据解析:支持JSON、XML等多种格式解析器。

扩展技巧

  • 结合享元模式复用无状态策略对象(如线程安全的计算策略)。
  • 使用Lambda表达式(Java/Python)简化小型策略类的定义。
参考资料
策略模式基础结构与角色定义
三国锦囊案例与设计思想
C++策略模式与对象生命周期管理
Python策略模式与动态语言特性
Java策略模式与线程安全实践
http://www.dtcms.com/a/99548.html

相关文章:

  • 深入理解前端防抖(Debounce)与节流(Throttle):原理、区别与实战示例
  • AWE 2025:当AI科技遇见智能家居
  • 请描述下你对vue生命周期的理解?在created和mounted这两个生命周期中请求数据有什么区别呢?
  • Java面向对象一篇通:从类与对象到Lambda(万字详解)
  • github免费编程类工具汇总与评估(二)
  • 2025年最新自动化/控制保研夏令营预推免面试真题分享(东南/浙大/华科清华)
  • mysql.8.4.4--初始化报错--libnuma.so.1缺失
  • Windows学习笔记(5)
  • Numpy进行数组函数操作
  • 鸿蒙项目源码-记账本app个人财物管理-原创!原创!原创!
  • 自动化发布工具CI/CD实践Jenkins介绍!
  • 动态规划--线性规划
  • Spring解决循环依赖
  • 【无人机路径规划】Matlab基于A星算法的无人机三维路径规划
  • maven高级
  • 微信小程序逆向开发
  • Java -jar运行jar包时可添加参数
  • ‌JVM 内存模型(JDK8+)
  • ModuleNotFoundError: No module named ‘demjson‘
  • JavaScript中的观察者模式
  • https://arxiv.org/
  • WebView展示广告对网站收益的影响分析(桌面平台非点击场景)
  • How to install OpenJ9 JDK 17 on Ubuntu 24.04
  • 《K230 从熟悉到...》矩形检测
  • 机器学习的一百个概念(2)Tomek 链接
  • 人工智能赋能医疗:开启智慧医疗新时代
  • Charles 抓包配置保姆教程(PC、IOS、Android)
  • 《强化学习基础概念:四大模型与两大损失》
  • 环境爬坑,切换python版本,让 jupyter 支持切换不同python版本内核
  • 家电产品智能屏方案,ESP32系列助力智能升级,物联网通信交互应用