Python编码系列—Python策略模式:灵活应对变化的算法策略

news2025/4/5 15:05:58

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中一起航行,共同成长,探索技术的无限可能。

🚀 探索专栏:学步_技术的首页 —— 持续学习,不断进步,让学习成为我们共同的习惯,让总结成为我们前进的动力。

🔍 技术导航:

  • 人工智能:深入探讨人工智能领域核心技术。
  • 自动驾驶:分享自动驾驶领域核心技术和实战经验。
  • 环境配置:分享Linux环境下相关技术领域环境配置所遇到的问题解决经验。
  • 图像生成:分享图像生成领域核心技术和实战经验。
  • 虚拟现实技术:分享虚拟现实技术领域核心技术和实战经验。

🌈 非常期待在这个数字世界里与您相遇,一起学习、探讨、成长。不要忘了订阅本专栏,让我们的技术之旅不再孤单!

💖💖💖 ✨✨ 欢迎关注和订阅,一起开启技术探索之旅! ✨✨

文章目录

  • 1. 背景介绍
  • 2. 原理
  • 3. 使用场景
  • 4. 代码样例
  • 5. 实际应用案例
  • 6. 总结

1. 背景介绍

在软件开发中,经常会遇到需要根据不同情况执行不同算法或行为的场景。策略模式(Strategy Pattern)提供了一种优雅的方式来管理和使用这些算法,使得算法可以在运行时被选择和更换。本文将深入探讨Python中的策略模式,包括其背景、原理、使用场景、代码实现和实际应用案例。

策略模式是一种行为型设计模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以互换使用。策略模式让算法的变化独立于使用算法的客户。
在这里插入图片描述

2. 原理

策略模式的核心原理包括:

  • 定义策略接口:定义所有支持的算法的公共接口。
  • 实现具体策略:实现策略接口,提供具体的算法实现。
  • 上下文配置策略:定义一个上下文类,它接受一个策略对象,并且可以设置和更换策略。

策略模式通过定义一系列算法并把它们封装起来,使得算法可以独立于使用它们的客户端而变化。这种模式让算法的变化不会影响到客户端,从而提高了程序的可扩展性和灵活性。下面详细探讨策略模式的核心原理:

定义策略接口
策略接口是策略模式的基础,它定义了所有支持的算法必须遵循的方法签名。这个接口充当了算法族的模板,确保了所有的策略类都具有统一的调用方式。策略接口通常包含一个或多个方法,这些方法声明了算法需要执行的操作。

class Strategy(ABC):
    @abstractmethod
    def execute(self, *args, **kwargs):
        """策略接口定义了所有策略类必须实现的execute方法"""
        pass

在这个例子中,Strategy是一个抽象基类,它定义了execute方法,该方法将由所有具体的策略类实现。

实现具体策略
具体策略类实现了策略接口,并提供了算法的具体实现。每个策略类都封装了一个特定的算法或行为,并且它们都遵循策略接口的约定。客户端可以通过这些策略类来执行不同的操作,而无需知道算法的具体细节。

class ConcreteStrategyA(Strategy):
    def execute(self, *args, **kwargs):
        print("Algorithm A is executed with arguments", args, kwargs)

class ConcreteStrategyB(Strategy):
    def execute(self, *args, **kwargs):
        print("Algorithm B is executed with arguments", args, kwargs)

在这个例子中,ConcreteStrategyAConcreteStrategyB是策略接口的具体实现,它们提供了不同的算法实现。

上下文配置策略
上下文(Context)是策略模式的另一个关键组成部分,它定义了与策略接口交互的方式。上下文维护一个对策略对象的引用,并且可以在运行时更改这个引用来改变行为。上下文允许客户端不直接与策略对象交互,而是通过上下文来调用策略的方法。

class Context:
    def __init__(self, strategy: Strategy):
        self._strategy = strategy

    def set_strategy(self, strategy: Strategy):
        self._strategy = strategy

    def execute_strategy(self, *args, **kwargs):
        """上下文通过策略对象调用其execute方法"""
        self._strategy.execute(*args, **kwargs)

在这个例子中,Context类接受一个策略对象,并提供了execute_strategy方法来执行策略的execute方法。客户端可以通过set_strategy方法来更换上下文中的策略对象。

通过这些核心原理,策略模式使得算法可以在运行时被选择和更换,而客户端代码则保持不变。这种模式在实际应用中非常广泛,特别是在需要根据不同条件执行不同算法的场景中。

3. 使用场景

策略模式适用于以下场景:

  • 需要在运行时切换算法:例如,支付系统中需要根据不同的用户选择不同的支付方式。
  • 需要避免使用多重条件判断:策略模式可以将算法封装起来,避免在条件判断中硬编码算法选择。
  • 需要扩展新的算法:当需要引入新的算法时,可以不修改现有代码,只需添加新的策略类。

4. 代码样例

以下是一个Python中实现策略模式的示例:

from abc import ABC, abstractmethod

# 定义策略接口
class Strategy(ABC):
    @abstractmethod
    def execute(self, context):
        pass

# 实现具体策略
class ConcreteStrategyA(Strategy):
    def execute(self, context):
        print(f"Executing Strategy A with context {context}")

class ConcreteStrategyB(Strategy):
    def execute(self, context):
        print(f"Executing Strategy B with context {context}")

# 定义上下文
class Context:
    def __init__(self, strategy: Strategy):
        self._strategy = strategy

    def set_strategy(self, strategy: Strategy):
        self._strategy = strategy

    def execute_strategy(self, context):
        self._strategy.execute(context)

# 客户端代码
if __name__ == "__main__":
    context = Context(ConcreteStrategyA())
    context.execute_strategy("Initial Context")

    # 切换策略
    context.set_strategy(ConcreteStrategyB())
    context.execute_strategy("New Context")

5. 实际应用案例

假设我们正在开发一个电子商务平台,需要根据不同的促销活动应用不同的折扣算法。我们可以使用策略模式来实现这一需求。

class DiscountStrategy(Strategy):
    def execute(self, price):
        return price * 0.9  # 10% 折扣

class NoDiscountStrategy(Strategy):
    def execute(self, price):
        return price  # 无折扣

class PromotionContext:
    def __init__(self, strategy: Strategy):
        self._strategy = strategy

    def apply_discount(self, price):
        return self._strategy.execute(price)

# 客户端代码
if __name__ == "__main__":
    promotion = PromotionContext(DiscountStrategy())
    print("Discounted Price:", promotion.apply_discount(100))

    # 切换策略
    promotion.set_strategy(NoDiscountStrategy())
    print("Price without discount:", promotion.apply_discount(100))

6. 总结

策略模式是一种非常实用的设计模式,它通过定义一系列算法的公共接口,使得算法可以在运行时被选择和更换。这种模式在需要灵活应对算法变化的场景中非常有用,如支付系统、促销折扣算法等。

设计模式是软件设计中的艺术,策略模式作为其中的一种,为我们提供了一种灵活的方式来管理和使用算法。希望本文能够帮助你在Python项目中更好地应用策略模式,提升代码的质量和灵活性。

🌟 在这篇博文的旅程中,感谢您的陪伴与阅读。如果内容对您有所启发或帮助,请不要吝啬您的点赞 👍🏻,这是对我最大的鼓励和支持。

📚 本人虽致力于提供准确且深入的技术分享,但学识有限,难免会有疏漏之处。如有不足或错误,恳请各位业界同仁在评论区留下宝贵意见,您的批评指正是我不断进步的动力!😄😄😄

💖💖💖 如果您发现这篇博文对您的研究或工作有所裨益,请不吝点赞、收藏,或分享给更多需要的朋友,让知识的力量传播得更远。

🔥🔥🔥 “Stay Hungry, Stay Foolish” —— 求知的道路永无止境,让我们保持渴望与初心,面对挑战,勇往直前。无论前路多么漫长,只要我们坚持不懈,终将抵达目的地。🌙🌙🌙

👋🏻 在此,我也邀请您加入我的技术交流社区,共同探讨、学习和成长。让我们携手并进,共创辉煌!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2155596.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

后端-navicat查找语句(单表与多表)

表格字段设置如图 语句&#xff1a; 1.输出 1.输出name和age列 SELECT name,age from student 1.2.全部输出 select * from student 2.where子语句 1.运算符&#xff1a; 等于 >大于 >大于等于 <小于 <小于等于 ! <>不等于 select * from stude…

大学生必看!60万人在用的GPT4o大学数学智能体有多牛

❤️作者主页&#xff1a;小虚竹 ❤️作者简介&#xff1a;大家好,我是小虚竹。2022年度博客之星&#x1f3c6;&#xff0c;Java领域优质创作者&#x1f3c6;&#xff0c;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;掘金年度人气作者&#x1…

Spring框架总体结构

1. Spring是什么 Spring 是一个开源框架 Spring 为简化企业级应用开发而生&#xff0c;使用 Spring 可以使简单的 JavaBean实现以前只有 EJB 才能实现的功能 Spring 是一个 IOC(DI) 和 AOP 容器框架 具体描述 Spring 轻量级&#xff1a;Spring 是非侵入性的 - 基于 Spring 开发…

【24华为杯数模研赛赛题思路已出】国赛B题思路丨附参考代码丨免费分享

2024年华为杯研赛B题解题思路 B题 WLAN组网中网络吞吐量建模 问题1 请根据附件WLAN网络实测训练集中所提供的网络拓扑、业务流量、门限、节点间RSSI的测试基本信息&#xff0c;分析其中各参数对AP发送机会的影响&#xff0c;并给出影响性强弱的顺序。通过训练的模型&#xff…

撤销与恢复的奥秘:设计模式之备忘录模式详解

备忘录模式 &#x1f3af; 备忘录模式&#xff08;Memento Pattern&#xff09;简介 备忘录模式 是一种行为型设计模式&#xff0c;用于保存对象的某一时刻状态&#xff0c;以便稍后可以恢复到该状态&#xff0c;而不破坏对象的封装性。备忘录模式将对象的状态封装在一个独立的…

技术周总结 09.16~09.22 周日(架构 C# 数据库)

文章目录 一、09.16 周一1.1&#xff09;问题01&#xff1a; 软件质量属性中"质量属性场景"、"质量属性环境分析"、"质量属性效用树"、"质量属性需求用例分析"分别是什么&#xff1f;1.2&#xff09;问题02&#xff1a; 软件质量属性中…

机器学习(1)sklearn的介绍和六个主要模块、估计器、模型持久化

文章目录 1.sklearn介绍2.sklearn的模块3.监督学习和无监督学习1. 监督学习 (Supervised Learning)例子 2. 无监督学习 (Unsupervised Learning)例子 4.估计器估计器的主要特性和方法包括&#xff1a;估计器的类型&#xff1a;示例&#xff1a;使用 scikit-learn 中的估计器 5.…

用最通俗易懂的语言和例子讲解三维点云

前言&#xff1a; 我整体的学习顺序是看的按B站那“唯一”的三维点云的视频学习的&#xff08;翻了好久几乎没有第二个...&#xff09;对于深度学习部分&#xff0c;由于本人并没有进行学习&#xff0c;所以没有深究。大多数内容都进行了自己的理解并找了很多网络的资源方便理解…

JavaScript可视化示例

JavaScript 可视化是指使用 JavaScript 编程语言来创建和操作图形、图表、动画等视觉元素的过程。以下是一些常见的 JavaScript 可视化库和工具&#xff0c;以及它们的主要特点&#xff1a; 1. D3.js 特点: D3.js&#xff08;Data-Driven Documents&#xff09;是一个非常强大…

MySQL高阶之存储过程

什么是存储过程? 存储过程可称为过程化SQL语言&#xff0c;是在普通SQL语句的基础上增加了编程语言的特点&#xff0c;把数据操作语句(DML)和查询语句(DQL)组织在过程化代码中&#xff0c;通过逻辑判断、循环等操作实现复杂计算的程序语言。 换句话说&#xff0c;存储过程其实…

Linux常用命令 笔记

Linux常用指令 查看命令ls 列出指定路径下的文件和目录cd 切换目录绝对路径相对路径 pwd 查看当前路径的绝对路径touch 创建空文件cat 显示文件内容echo 显示内容 & 写入文件vim 文本编辑器打开文件编辑文件保存退出 mkdir 创建目录rm 删除文件&目录删除文件删除目录 定…

java重点学习-设计模式

十三 设计模式 工厂模式&#xff1a;spring中使用&#xff08;目的是&#xff1a;解耦&#xff09; 1.简单工厂 所有的产品都共有一个工厂&#xff0c;如果新增产品&#xff0c;则需要修改代码&#xff0c;违反开闭原则是一种编程习惯&#xff0c;可以借鉴这种编程思路 2.工厂方…

分布式锁优化之 防死锁 及 过期时间的原子性保证(优化之设置锁的过期时间)

文章目录 1、AlbumInfoApiController --》testLock()2、AlbumInfoServiceImpl --》testLock()3、问题&#xff1a;可能会释放其他服务器的锁。 在Redis中设置一个名为lock的键&#xff0c;值为111&#xff0c;并且只有在该键不存在时才设置&#xff08;即获取锁&#xff09;。同…

为解决bypy大文件上传报错—获取百度云文件直链并使用Aria2上传文件至服务器

问题描述 一方面组内的服务器的带宽比较小&#xff0c;另一方面使用bypy方式进行大文件(大于15G)上传时会报错&#xff08;虽然有时可以成功上传&#xff0c;但是不稳定&#xff09;&#xff1a; 解决方式 总体思路: 获得云盘需要下载文件的直链复制直链到服务器中使用自带…

Selenium with Python学习笔记整理(网课+网站持续更新)

本篇是根据学习网站和网课结合自己做的学习笔记&#xff0c;后续会一边学习一边补齐和整理笔记 官方学习网站在这获取&#xff1a; https://selenium-python.readthedocs.io/getting-started.html#simple-usage WEB UI自动化环境配置 (推荐靠谱的博客文章来进行环境配置,具…

OpenCV运动分析和目标跟踪(3)计算图像序列的加权平均值函数accumulateWeighted()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 更新一个运行平均值。 该函数计算输入图像 src 和累积器 dst 的加权和&#xff0c;使得 dst 成为帧序列的运行平均值&#xff1a; dst ( x , y…

CANopen通讯协议笔记

CANopen通讯协议笔记 CANopen 通信对象编号CANopen整体框架网络管理&#xff08;NMT&#xff09;主要任务上线报文心跳报文过程数据对象&#xff08;PDO&#xff09;SDO服务数据对象对象字典概述 CANopen 通信对象编号 CANopen报文传输采用 CAN 标准帧格式。 这里的CAN-ID也叫…

ARM(Day 2)

一、作业 &#xff08;1&#xff09;汇编代码 .text.globl _start_start:mov r0, #0x5mov r1, #0x10比较r0,r1 是否相等 相等执行stop 不相等执行下一步比较&#xff08; r0 > r1 ?&#xff09;cmp r0, r1 比较实际在做减法 (YES NO )subhi r0, r0, r1 r0 > r1 …

浅谈Spring Cloud:OpenFeign

RestTemplate 方式调用存在的问题&#xff1a; String url "http://userservice/user/" order.getUserId(); User user restTemplate.getForObject(url, User.class); 这是通过URL地址来访问的。但是&#xff1a; 代码可读性差&#xff0c;编程体验不统一参数复…

NCNN 源码(1)-模型加载-数据预处理-模型推理

参考 ncnn 第一个版本的代码。 0 整体流程 demo&#xff1a;squeezenet ncnn 自带的一个经典 demo&#xff1a;squeezenet 的代码: // 网络加载 ncnn::Net squeezenet; squeezenet.load_param("squeezenet_v1.1.param"); squeezenet.load_model("squeezenet_…