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

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

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

🔍 技术导航:

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

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

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

文章目录

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

1. 背景介绍

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

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

2. 原理

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

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

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

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

class Strategy(ABC):@abstractmethoddef 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 = strategydef set_strategy(self, strategy: Strategy):self._strategy = strategydef 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):@abstractmethoddef 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 = strategydef set_strategy(self, strategy: Strategy):self._strategy = strategydef 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 = strategydef 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.xdnf.cn/news/147343.html

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

相关文章

微软AI核电计划

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

Django学习实战篇六(适合略有基础的新手小白学习)(从0开发项目)

前言: 上一章中,我们完成了页面样式的配置,让之前简陋的页面变得漂亮了些。 整理一下目前已经完成的系统,从界面上看,已经完成了以下页面: 首页分类列表页标签列表页口博文详情页 这离我们的需求还有些距离&#xff0…

Python | Leetcode Python题解之第423题从英文中重建数字

题目: 题解: class Solution:def originalDigits(self, s: str) -> str:c Counter(s)cnt [0] * 10cnt[0] c["z"]cnt[2] c["w"]cnt[4] c["u"]cnt[6] c["x"]cnt[8] c["g"]cnt[3] c["h…

【完整梳理验证】企业微信第三方应用接入全流程java版

企业微信第三方应用接入全流程java版 1. 概念与流程1.1 概念1、企业内部应用2、`第三方应用`3、代开发自建应用1.2 流程1.2.1 全局流程1.2.2 应用配置1.2.3 数据流程2. 核心文档2.1 理解第三方应用开发流程和概念2.1.1 应用开发阶段2.1.2 应用推广阶段2.1.3 基本流程1)前期应用…

C++ | Leetcode C++题解之第421题数组中两个数的最大异或值

题目: 题解: struct Trie {// 左子树指向表示 0 的子节点Trie* left nullptr;// 右子树指向表示 1 的子节点Trie* right nullptr;Trie() {} };class Solution { private:// 字典树的根节点Trie* root new Trie();// 最高位的二进制位编号为 30static…

leetcode第十题:正则表达式匹配

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符* 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s 的,而不是部分字符串。 示例 1: 输入:s…

TMS320F28335的定时器中断实验

TTMS320F28335 的 CPU 定时器有 3 个且均为 32 位,分别是 Timer0、Timer1、Timer2, 其中 Timer2 是为操作系统 DSP/BIOS 保留的,当未移植操作系统时,可用来做普 通的定时器。这三个定时器的中断信号分别为 TINT0,TINT1,TINT2,分别对应中断向量于 INT1,INT13,INT14。 1 …

使用 NCache 将 Java 微服务扩展到极致性能

微服务已成为软件开发领域的一种变革性架构方法,提供了从整体结构到更加模块化和可扩展的系统的范式转变。微服务的核心是将复杂的应用程序分解为更小的、可独立部署的服务,这些服务可以无缝通信,从而提高敏捷性、灵活性和易维护性。这种分散…

动态规划day38|322. 零钱兑换(背包满了吗?最小值怎么表示?)、279. 完全平方数、139. 单词拆分、多重背包要点、背包问题大总结

动态规划day38|322. 零钱兑换(背包满了吗?最小值怎么表示?)、279. 完全平方数、139. 单词拆分、多重背包要点、背包问题大总结 322. 零钱兑换279. 完全平方数139. 单词拆分多重背包要点背包问题大总结 322. 零钱兑换 给你一个整数…

后端-项目创建与sql

1.创建文件 1.在webcontent下创建.html文件 2. 在java resources下创建包,右键包创建servlet服务生.(要是创建普通的类,里面的注解里的东西不能重复) 注意:class的名字要和文件名一样,注解里的servlet是独一无二的。 …

最新 idea 2024 入门使用详细教程

IntelliJ IDEA:这是一款由JetBrains公司开发的Java集成开发环境(Integrated Development Environment),被广泛认为是目前Java开发者最好的集成开发工具之一。它支持Java、Groovy、Kotlin等多种编程语言,并且提供了丰富…

HCIA--实验十七:EASY IP的NAT实现

一、实验内容 1.需求/要求: 通过一台PC,一台交换机,两台路由器来成功实现内网访问外网。理解NAT的转换机制。 二、实验过程 1.拓扑图: 2.步骤: 1.PC1配置ip地址及网关: 2.AR1接口配置ip地址&#xff1…

Java免税商品优选商城:Spring Boot实战

第二章 系统开发关键技术 2.1 JAVA技术 Java主要采用CORBA技术和安全模型,可以在互联网应用的数据保护。它还提供了对EJB(Enterrise JavaBeans)的全面支持,java servlet AI,JS(java server ages&#xff09…

Tomcat中BIO和NIO的区别(Tomcat)

BIO Tomcat中BIO的模型和理论很简单,例图如下 1.Acceptor线程死循环阻塞接收客户端的打过来的socket请求 2.接收到请求之后打包成一个SocketProcessor(Runnable),扔到线程池中读取/写入数据 参数配置 1.Acceptor默认线程是1&#…

2024年1月Java项目开发指南17:自动接口文档配置

Knife4j 文档 :https://doc.xiaominfo.com/ 有能力的建议自己去看文档配置,本文仅做参考,因为官方文档会更新,本文不会,以后说不定本文就过时了。 ok,我们继续。虽然本文是2024年1月Java项目开发指南17&…

JVM面试题-说一下JVM主要组成部分及其作用

总体来说,方法区和堆是所有线程共享的内存区域;而虚拟机栈、本地方法栈和程序计数器的运行是线程私有的内存区域,运行时数据区域就是我们常说的JVM的内存。 类加载子系统:根据给定的全限定名类名(如:java.lang.Object…

使用Kong开源API网关的保姆级教程

什么是Kong? Kong是一个开源的、云原生、高性能的API网关,可以轻松地为任何服务提供管理、保护和扩展。它提供了一个可扩展的插件生态系统,可以满足各种各样的需求,如身份验证、授权、限流、监控等。 安装Kong 1. 环境准备 操作系统: CentOS、Ubuntu等主流Linux发行版D…

微信小程序IOS真机调试-onPullDownRefresh和onReachBottom不生效

切换真机调试2.0版本 勾选JS编译成ES5 如果使用了 uniapp,这里也需要勾选 重新启动

【Proteus单片机仿真】基于51单片机的循迹小车避障+气体传感器和温度传感器系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 开机即两个直流电机运转,然后三个气体传感器,如果超过阈值,即蜂鸣器报警; 超声波传感器,如果检测到障碍,电机停止&#xff1…

深度学习02-pytorch-06-张量的形状操作

在 PyTorch 中,张量的形状操作是非常重要的,可以让你灵活地调整和处理张量的维度和数据结构。以下是一些常用的张量形状函数及其用法,带有详细解释和举例说明: 1. reshape() 功能: 改变张量的形状,但不改变数据的顺序…