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

重温设计模式--13、策略模式

策略模式介绍

文章目录

      • 策略模式介绍
      • C++ 代码示例

策略模式是一种行为设计模式,它允许在运行时选择算法的行为。该模式将算法的定义和使用分离开来,使得算法可以独立于使用它的客户端而变化,提高了代码的灵活性和可维护性。
在这里插入图片描述

其主要包含以下几个角色:

  1. 抽象策略(Strategy):定义了一个公共接口,用于所有具体策略类实现,这个接口声明了算法的方法签名,客户端通过这个接口来调用具体的算法。
  2. 具体策略(Concrete Strategy):实现了抽象策略接口,提供具体的算法实现逻辑。不同的具体策略类实现了不同的算法,可以根据具体需求进行替换。
  3. 上下文(Context):持有一个对抽象策略的引用,通过这个引用调用具体策略的算法方法。上下文类负责与客户端交互,并根据情况决定使用哪个具体策略。

使用策略模式的好处在于:

  • 可扩展性强:当需要添加新的算法时,只需创建新的具体策略类实现抽象策略接口即可,不需要修改现有代码的核心逻辑,符合开闭原则(对扩展开放,对修改关闭)。
  • 代码复用性高:具体策略类可以在不同的上下文中被复用,只要符合抽象策略定义的接口规范就行。
  • 便于维护和测试:由于每个算法都独立在具体策略类中实现,代码结构清晰,便于单独对各个算法进行维护和测试。

C++ 代码示例

以下是一个简单的用 C++ 实现的策略模式示例,模拟一个电商系统中不同的折扣策略计算商品最终价格的场景。

#include <iostream>
#include <string>// 抽象策略类,定义折扣计算的接口
class DiscountStrategy {
public:virtual double calculateDiscount(double price) = 0;virtual ~DiscountStrategy() {}
};// 具体策略类1:满减折扣策略
class FullReductionStrategy : public DiscountStrategy {
public:double calculateDiscount(double price) override {if (price >= 200) {return price * 0.2;  // 满200减20%}return 0;}
};// 具体策略类2:固定折扣策略
class FixedDiscountStrategy : public DiscountStrategy {
public:double calculateDiscount(double price) override {return price * 0.1;  // 固定打9折}
};// 上下文类,持有折扣策略引用并执行折扣计算
class ShoppingCart {
public:ShoppingCart(DiscountStrategy* strategy) : m_strategy(strategy) {}void setDiscountStrategy(DiscountStrategy* strategy) {m_strategy = strategy;}double calculateFinalPrice(double price) {double discount = m_strategy->calculateDiscount(price);return price - discount;}private:DiscountStrategy* m_strategy;
};int main() {// 创建具体策略对象FullReductionStrategy fullReduction;FixedDiscountStrategy fixedDiscount;// 创建上下文对象,并传入具体策略对象ShoppingCart cart1(&fullReduction);ShoppingCart cart2(&fixedDiscount);double price = 300;std::cout << "使用满减策略,商品价格为 " << price << " 时,最终价格: " << cart1.calculateFinalPrice(price) << std::endl;std::cout << "使用固定折扣策略,商品价格为 " << price << " 时,最终价格: " << cart2.calculateFinalPrice(price) << std::endl;// 更换策略并重新计算价格cart1.setDiscountStrategy(&fixedDiscount);std::cout << "更换为固定折扣策略后,商品价格为 " << price << " 时,最终价格: " << cart1.calculateFinalPrice(price) << std::endl;return 0;
}

下面对上述代码进行详细解释:

  1. 抽象策略类 DiscountStrategy

    • 它定义了一个纯虚函数 calculateDiscount,这个函数接收商品价格作为参数,用于计算折扣金额,返回值是折扣的具体数值(以价格的比例形式体现)。纯虚函数的存在使得这个类成为抽象类,不能直接实例化,必须由具体的子类来实现其 calculateDiscount 方法。
    • 虚析构函数 ~DiscountStrategy() 的定义是为了保证在通过基类指针删除派生类对象时能够正确调用派生类的析构函数,避免内存泄漏等问题,遵循了多态情况下正确析构的原则。
  2. 具体策略类

    • FullReductionStrategy:实现了 DiscountStrategy 抽象策略接口,在 calculateDiscount 方法中定义了满减的折扣逻辑,即当商品价格大于等于200时,给予20%的折扣,否则没有折扣(返回0)。
    • FixedDiscountStrategy:同样实现了抽象接口,其折扣逻辑是固定给予商品价格10%的折扣,无论商品价格具体是多少。
  3. 上下文类 ShoppingCart

    • 它有一个私有成员变量 m_strategy,类型是指向 DiscountStrategy 抽象策略类的指针,通过构造函数或者 setDiscountStrategy 方法来初始化或更换这个指针所指向的具体策略对象。
    • calculateFinalPrice 方法用于根据当前持有的具体策略计算商品的最终价格,它先调用 m_strategy 指向的具体策略对象的 calculateDiscount 方法获取折扣金额,然后用商品原价减去折扣金额得到最终价格。
  4. main 函数部分

    • 首先创建了两个具体策略类的对象 fullReduction(满减策略)和 fixedDiscount(固定折扣策略)。
    • 接着创建了两个 ShoppingCart 上下文对象 cart1cart2,并分别在构造函数中传入不同的具体策略对象,这样 cart1 初始使用满减策略,cart2 使用固定折扣策略。然后通过调用 calculateFinalPrice 方法分别计算并展示了商品价格为300时,不同策略下的最终价格。
    • 之后又通过 cart1setDiscountStrategy 方法将其使用的策略更换为固定折扣策略,并再次计算和展示了最终价格,体现了策略模式可以在运行时灵活切换算法(策略)的特点。

通过这个示例可以看到,策略模式将不同的折扣算法封装在各自的具体策略类中,而 ShoppingCart 上下文类只需要关心抽象策略接口,根据具体情况使用不同的具体策略来计算最终价格,使得代码结构清晰,易于扩展和维护。例如,如果后续要添加一个新的折扣策略(如会员专享折扣策略等),只需要创建一个新的具体策略类实现 DiscountStrategy 接口,并在需要的地方(如 ShoppingCart 上下文对象中)使用这个新策略即可,不需要修改原有的核心代码逻辑。

http://www.lryc.cn/news/516390.html

相关文章:

  • 【Rust自学】10.7. 生命周期 Pt.3:输入输出生命周期与3规则
  • 产品经理-竞品分析
  • 51单片机——8*8LED点阵
  • 力扣第136题:只出现一次的数字 巧用异或
  • TCP 如何获取端口信息
  • RabbitMQ发布确认高级篇(RabbitMQ Release Confirmation Advanced Edition)
  • 福建省乡镇界面数据arcgis格式shp乡镇名称和编码无偏移坐标内容测评
  • Kafka 消费者
  • 人形机器人当前现状与挑战:从技术突破到未来发展
  • 6 网络编程
  • 智能边缘计算:开启智能新时代
  • AI投资分析:用于股票评级的大型语言模型(LLMs)
  • 初始SpringBoot:详解特性和结构
  • 【计算机网络】深入解析OSI和TCP/IP模型:网络请求的底层处理过程
  • 快速学习 pytest 基础知识
  • Ae:合成设置 - 3D 渲染器
  • java异步判断线程池所有任务是否执行完
  • 25.1.3 UART串口通信
  • 如何使用脚手架工具开始,快速搭建一个 Express 项目的基础架构
  • 防止密码爆破debian系统
  • 高阶知识库搭建实战六、(向量数据库Faiss安装)(练习推荐)
  • 微信小程序获取图片使用session(上篇)
  • 代码随想录算法训练营第七十天 | 拓扑排序精讲,Dijkstra(朴素版)精讲,Dijkstra(堆优化版)精讲
  • 【保姆级爬虫】微博关键词搜索并获取博文和评论内容(python+selenium+chorme)
  • Excel 打印时-预览界面内容显示不全
  • nginx-限流(请求/并发量)
  • Vue——使用html2pdf插件,下载pdf文档到本地
  • 每日一题:BM1 反转链表
  • CSS 实现字体颜色渐变
  • 【软考网工笔记】计算机基础理论与安全——网络安全