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

Python实现设计模式-策略模式

策略模式是一种行为型设计模式,它定义了一系列算法或策略,并将它们封装成独立的类,使得它们可以相互替换,而不影响客户端的使用。

在策略模式中,算法或策略被封装在单独的策略类中,这些策略类实现了相同的接口或继承自相同的抽象类。客户端通过持有策略类的引用来调用相应的算法或策略,而不是在自身的代码中直接实现具体的算法或策略。

策略模式的核心思想是将算法的选择和使用与具体的算法实现解耦,使得算法可以独立于客户端的代码进行修改、扩展和替换。这样可以提高代码的灵活性、可维护性和可扩展性。

使用策略模式的步骤如下:

  1. 定义策略接口或抽象类,其中声明并定义了策略的方法。
  2. 实现具体的策略类,实现策略接口或继承抽象策略类,并实现具体的算法或策略。
  3. 在客户端中持有策略类的引用,并将具体的策略类传递给客户端进行调用。

策略模式的优点包括提高代码灵活性、重用性和可扩展性,同时也提高了代码的可读性和维护性。然而,策略模式可能会增加类的数量,并要求使用者了解不同的策略类。

总结起来,策略模式是将算法或策略封装成独立的类,实现了算法和客户端的解耦,提高了代码的灵活性和可维护性。

策略模式的实现原理是基于面向对象的封装和多态性。

在策略模式中,我们首先将每个具体的策略封装成独立的类,每个类都实现了相同的接口或继承自相同的抽象类。这个接口或抽象类定义了策略类应该具备的方法。

然后,我们在上下文类中持有一个策略对象,并在上下文类中定义了一个方法,用于执行策略。当上下文类的方法被调用时,它会调用策略对象的方法来执行具体的策略。

由于每个具体的策略都实现了相同的接口或继承自相同的抽象类,上下文类可以在运行时动态选择不同的策略对象,从而实现策略的切换。

策略模式的实现原理可以通过以下步骤概括:

  1. 定义一个策略接口或抽象类,其中包含策略类应该具备的方法。
  2. 实现具体的策略类,每个具体的策略类都实现了策略接口或继承自策略抽象类,并覆盖了接口或抽象类中的方法。
  3. 在上下文类中持有一个策略对象,并提供一个方法来执行策略。在执行策略的方法中,调用策略对象的方法来执行具体的策略。
  4. 在使用策略模式时,创建具体的策略对象,并将其传递给上下文类,从而实现策略的切换。

通过策略模式,我们实现了将不同的策略封装成了独立的类,并通过上下文类来执行具体的策略。这样,我们可以轻松地扩展和修改策略,而不需要修改上下文类的代码。这符合开闭原则,并使得代码更加清晰、可维护和可扩展。

策略模式的优点包括:

  1. 提高代码灵活性:通过将策略封装成独立的类,可以在运行时动态切换不同的策略,从而提高了代码的灵活性。
  2. 提高代码重用性:不同的策略可以通过继承或实现相同的接口来实现,从而提高了代码的重用性。
  3. 增强可扩展性:添加新的策略类不需要修改现有的代码,只需要新增一个策略类即可,这符合开闭原则。
  4. 提高了代码可读性:将不同的策略封装成独立的类并使用相同的接口,使得代码更加清晰、易于理解和维护。

策略模式的缺点包括:

  1. 增加了类的数量:每个具体策略都需要一个对应的类,这可能会增加类的数量。
  2. 使用者需要了解不同的策略类:使用者在选择策略时需要了解不同的策略类,这可能会增加使用者的工作量。

应用场景:

  1. 系统中存在多种算法或策略,并且需要在运行时动态选择不同的算法或策略。
  2. 需要将具体的算法或策略与使用它的代码解耦,以提高代码的灵活性和可维护性。
  3. 需要通过继承或实现相同的接口来实现不同的算法或策略,以提高代码的重用性。
  4. 需要在不同的场景下使用不同的算法或策略,以实现不同的功能或行为。

例如,一个电商平台可能需要根据不同的促销活动制定不同的优惠策略,例如打折、满减、赠品等。这时可以使用策略模式,将每种促销策略封装成独立的类,然后在运行时根据不同的促销活动选择不同的策略对象。这样可以灵活地切换促销策略,并且不需要修改现有的代码。

下面是一个使用Python实现策略模式的简单示例:


class Strategy: # 策略接口或抽象类def execute(self):passclass Context: # 在上下文类中持有一个策略对象,并提供一个方法来执行策略def __init__(self, strategy):self.strategy = strategydef run_strategy(self):self.strategy.execute()class ConcreateStrategyA(Strategy): # 实现具体的策略类def execute(self):print("执行策略A")
class ConcreateStrategyB(Strategy): # 实现具体的策略类def execute(self):print("执行策略B")strategy_a = ConcreateStrategyA()
context = Context(strategy_a)
context.run_strategy()strategy_b = ConcreateStrategyB()
context = Context(strategy_b)
context.run_strategy()

在上面的示例中,我们定义了一个Context类来扮演上下文角色,该类在构造函数中接受一个Strategy对象作为参数,并通过run_strategy方法来执行该策略。

我们还定义了一个Strategy类作为策略的抽象基类,它包含一个execute方法。然后,我们派生出两个具体的策略类ConcreteStrategyAConcreteStrategyB,它们分别实现了execute方法。

在使用策略模式时,我们可以根据实际情况创建不同的策略对象,并将其传递给Context对象来执行相应的策略。在上面的示例中,我们通过创建一个ConcreteStrategyA对象和一个ConcreteStrategyB对象来演示不同的策略执行。输出结果为:

执行策略A
执行策略B

这说明策略模式成功地将不同的策略封装成了独立的类,并实现了动态切换策略的能力。

相关文章:

Python实现设计模式-策略模式

策略模式是一种行为型设计模式,它定义了一系列算法或策略,并将它们封装成独立的类,使得它们可以相互替换,而不影响客户端的使用。 在策略模式中,算法或策略被封装在单独的策略类中,这些策略类实现了相同的…...

详解SpringCloud微服务技术栈:深入ElasticSearch(4)——ES集群

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:详解SpringCloud微服务技术栈:深入ElasticSearch(3)——数据同步(酒店管理项目&a…...

AlmaLinux上安装Docker

AlmaLinux上安装Docker 文章目录 AlmaLinux上安装Docker一、前言二、具体步骤1、Docker 下载更新系统包索引:添加Docker仓库:安装Docker引擎: 2、Docker服务启动启动Docker服务:设置Docker开机自启: 3、Docker 安装验证…...

熟悉MATLAB 环境

一、问题描述 熟悉MATLAB 环境。 二、实验目的 了解Matlab 的主要功能,熟悉Matlab 命令窗口及文件管理,Matlab 帮助系统。掌握命令行的输入及编辑,用户目录及搜索路径的配置。了解Matlab 数据的特点,熟悉Matlab 变量的命名规则&a…...

【数据库数据恢复】Oracle数据库ASM磁盘组数据恢复案例

oracle数据库故障&分析: oracle数据库ASM磁盘组掉线,ASM实例不能挂载。数据库管理员尝试修复数据库,但是没有成功。 oracle数据库数据恢复过程: 1、将oracle数据库所涉及磁盘以只读方式备份。后续的数据分析和数据恢复操作都…...

STM32CubeMX教程31 USB_DEVICE - HID外设_模拟键盘或鼠标

目录 1、准备材料 2、实验目标 3、模拟鼠标实验流程 3.0、前提知识 3.1、CubeMX相关配置 3.1.0、工程基本配置 3.1.1、时钟树配置 3.1.2、外设参数配置 3.1.3、外设中断配置 3.2、生成代码 3.2.0、配置Project Manager页面 3.2.1、设初始化调用流程 3.2.2、外设中…...

知道Wi-Fi名称和密码之后自动连接

这里写自定义目录标题 有Wi-Fi名称和密码自动连接Wi-Fi主Activity服务类 WIFIStateReceiver工具类 WIFIConnectionManager 有Wi-Fi名称和密码自动连接Wi-Fi 主Activity public class MainActivity extends AppCompatActivity implements View.OnClickListener{private static…...

本地搭建Plex私人影音网站并结合内网穿透实现公网远程访问

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

【算法】拦截导弹(线性DP)

题目 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。 但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。 某天,雷达捕捉到敌国的导弹来袭。 由于该系…...

记 doris 加载压缩文件(lzo、snappy)pr

做了一个case,是doris支持加载lzo压缩文件。[improvement](load) Enable lzo & Remove dependency on Markus F.X.J. Oberhumers lzo library by HowardQin Pull Request #30573 apache/doris (github.com) 其实doris里已经支持了 lzo,这个case源…...

【Leetcode】2670. 找出不同元素数目差数组

文章目录 题目思路代码结果 题目 题目链接 给你一个下标从 0 开始的数组 nums ,数组长度为 n 。 nums 的 不同元素数目差 数组可以用一个长度为 n 的数组 diff 表示,其中 diff[i] 等于前缀 nums[0, …, i] 中不同元素的数目 减去 后缀 nums[i 1, …, …...

༺༽༾ཊ—Unity之-01-工厂方法模式—ཏ༿༼༻

首先创建一个项目, 在这个初始界面我们需要做一些准备工作, 建基础通用文件夹, 创建一个Plane 重置后 缩放100倍 加一个颜色, 任务:使用工厂方法模式 创建 飞船模型, 首先资源商店下载飞船模型&#xff0c…...

QT仪表盘小工具

头文件: /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE…...

【2024】大三寒假再回首:缺乏自我意识是毒药,反思和回顾是解药

2024年初,学习状态回顾 开稿时间:2024-1-23 归家百里去,飘雪送客迟。 搁笔日又久,一顾迷惘时。 我们饱含着过去的习惯,缺乏自我意识是毒药,反思和回顾是解药。 文章目录 2024年初,学习状态回顾一…...

计算机网络——网络层(3)

计算机网络——网络层(3) 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU)1 网络层——控制平面因特网中自治系统内部的路由选择总括考虑因素总结 ISP之间的路由选择:BGP考虑因素总结 SDN控制层面重要组件和功能总结 ICMP主要功能和特点…...

ROS2 学习笔记12:使用 colcon 构建软件包

ROS2 学习笔记12:使用 colcon 构建软件包 Background 背景Prerequisites 前提1 Install colcon2 Install ROS 2 Basics 基础1 Create a workspace2 Add some sources3 Source an underlay4 Build the workspace5 Run tests6 Source the environment7 Try a demo Cre…...

基于JAVA+SpringBoot+Vue的前后端分离的医院管理系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背景介绍: 随着计算机科学的迅猛…...

npm淘宝镜像过期解决办法

npm淘宝镜像过期解决办法 因为npm 官方镜像(registry.npmjs.org)在国内访问很慢,我们基本上都会选择切换到国内的一些 npm 镜像(淘宝镜像、腾讯云镜像等)。由于淘宝原来的镜像(registry.npm.taobao.org&am…...

Arduino 官网上下载和使用开发板

在 Arduino 官网上下载和使用开发板可以按照以下步骤进行: 打开浏览器,访问 Arduino 官网(https://www.arduino.cc/)。在官网首页,可以看到各种型号的 Arduino 开发板和相关产品。根据自己的需求选 择合适的开发板型号…...

k8s学习-DaemonSet和Job

1.1DaemonSet是什么 Deployment部署的副本Pod会分布在各个Node上,每个Node都可能运行好几个副本。DaemonSet的不同之处在于:每个Node上最多只能运行⼀个副本。DaemonSet的典型应用场景有: (1)在集群的每个节点上运⾏存…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

算术操作符与类型转换:从基础到精通

目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...

WebRTC调研

WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...

如何做好一份技术文档?从规划到实践的完整指南

如何做好一份技术文档?从规划到实践的完整指南 🌟 嗨,我是IRpickstars! 🌌 总有一行代码,能点亮万千星辰。 🔍 在技术的宇宙中,我愿做永不停歇的探索者。 ✨ 用代码丈量世界&…...