【Python笔记-设计模式】策略模式

news2024/9/21 14:31:06

一、说明

策略模式是一种行为设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以互相替换。

(一) 解决问题

在需要根据不同情况选择不同算法或策略,规避不断开发新需求后,代码变得非常臃肿难以维护管理。

(二) 使用场景

  • 当一个类有多个行为,而且这些行为在不同的情况下有不同的实现时
  • 当需要在运行时动态地选择算法时
  • 当一个类的一部分行为是固定的,一部分是可变的时,可以使用策略模式来封装可变的部分

二、结构

  1. 上下文(Context)维护指向具体策略的引用,且仅通过策略接口与该对象进行交流。
  2. 策略(Strategy)接口是所有具体策略的通用接口,它声明了一个上下文用于执行策略的方法。
  3. 具体策略(ConcreteStrategies)实现了上下文所用算法的各种不同变体。
  4. 当上下文需要运行算法时,它会在其已连接的策略对象上调用执行方法。上下文不清楚其所涉及的策略类型与算法的执行方式。
  5. 客户端(Client)会创建一个特定策略对象并将其传递给上下文。上下文则会提供一个设置器以便客户端在运行时替换相关联的策略。

三、伪代码

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
策略模式

例:商场优惠活动,选择不同的优惠策略,最后计算的价格也不同。而如果增加新算法,只需增加一个策略类,无需修改现有代码
"""

from abc import ABC, abstractmethod


class DiscountStrategy(ABC):
    """抽象策略类"""

    @abstractmethod
    def apply_discount(self, price):
        pass


class PercentDiscount(DiscountStrategy):
    """具体策略类:打折策略"""

    def __init__(self, discount_percent):
        self.discount_percent = discount_percent

    def apply_discount(self, price):
        return price * (1 - self.discount_percent / 100)


class FullReduction(DiscountStrategy):
    """具体策略类:满减策略"""

    def __init__(self, full_price, reduction_price):
        self.full_price = full_price
        self.reduction_price = reduction_price

    def apply_discount(self, price):
        return price - (price // self.full_price) * self.reduction_price


class Promotion:
    """上下文类:商场促销"""

    def __init__(self, discount_strategy):
        self.discount_strategy = discount_strategy

    def apply_discount(self, price):
        return self.discount_strategy.apply_discount(price)


if __name__ == "__main__":
    """
        打折后价格:80.0
        满减后价格:100
    """
    # 商品原价
    original_price = 100
    # 选择打折策略,打8折
    promotion = Promotion(PercentDiscount(20))
    discounted_price = promotion.apply_discount(original_price)
    print(f"打折后价格:{discounted_price}")

    # 选择满减策略,满200减50
    promotion = Promotion(FullReduction(200, 50))
    discounted_price = promotion.apply_discount(original_price)
    print(f"满减后价格:{discounted_price}")

四、优缺点

优点

  • 灵活性和可扩展性:策略模式将算法封装成独立的类,使得可以独立地添加、修改或替换算法,而不影响到客户端的代码,从而提高了代码的灵活性和可扩展性。
  • 易于维护:由于算法被封装在独立的类中,使得每个算法都有自己的类,易于理解和维护。
  • 避免条件语句的使用:策略模式避免了使用大量的条件语句来选择不同的算法,使得代码更加清晰和易于理解。
  • 符合开闭原则:策略模式符合开闭原则,即对扩展开放,对修改关闭,可以通过添加新的策略类来扩展功能,而不需要修改现有的代码。

缺点

  • 增加了类的数量:每个具体策略都需要一个对应的策略类,可能会增加类的数量。
  • 客户端必须知道所有的策略类:客户端必须知道所有的策略类,并且在使用时需要显式地选择合适的策略类,这可能会增加客户端的复杂性。
  • 如果算法极少发生改变,那么没有任何理由引入新的类和接口。使用该模式只会让程序过于复杂。

【Python笔记】设计模式-CSDN博客

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

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

相关文章

python实现常见一元随机变量的概率分布

一. 随机变量 随机变量是一个从样本空间 Ω \Omega Ω到实数空间 R R R的函数,比如随机变量 X X X可以表示投骰子的点数。随机变量一般可以分为两类: 离散型随机变量:随机变量的取值为有限个。连续型随机变量:随机变量的取值是连…

VSCode上搭建C/C++开发环境(vscode配置c/c++环境)Windows系统---保姆级教程

引言劝退 VSCode,全称为Visual Studio Code,是由微软开发的一款轻量级,跨平台的代码编辑器。大家能来搜用VSCode配置c/c,想必也知道VSCode的强大,可以手握一个VSCode同时编写如C,C,C#&#xff…

网神 SecGate 3600 防火墙 sys_export_conf_local_save 文件读取漏洞

免责声明:文章来源互联网收集整理,请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该…

PMP证书的含金量如何?

PMP含金量更多的是“敲门砖”作用,公司招聘的门槛,现在坐项目的大部分都需要PMP/NPDP证书。 当然现在PMP管理模式也很热门,对企业发展很有利,各大企业都有引进改良应用在公司的项目上,之前在校友群里面大家在讨论PMP …

springboot+vue+mysql项目使用的常用注解

实体类常用注解 Data Data 是一个 Lombok 提供的注解&#xff0c;使用 Data 注解可以简化代码&#xff0c;使代码更加简洁易读。 作用&#xff1a;自动为类生成常用的方法&#xff0c;包括 getter、setter、equals、hashCode 和 toString 等需要加Lombok的依赖 <depende…

中小企业“数智未来”行动|ZStack Cloud 荣获“推荐方案”奖

2月29日&#xff0c;以“数智未来 共创数字时代新篇章”为主题的中小企业“数智未来”行动在京成功举办&#xff0c;本次活动由中央广播电视总台央视频和中国中小企业协会作为联合观察单位&#xff0c;带来了一系列帮助中小企业成就业务新价值和数智化升级的优秀产品和方案&…

20240301-2-ZooKeeper面试题(二)

11. Chroot 特性 3.2.0 版本后&#xff0c;添加了 Chroot 特性&#xff0c;该特性允许每个客户端为自己设置一个命名空间。如果一个客户端设置了 Chroot&#xff0c;那么该客户端对服务器的任何操作&#xff0c;都将会被限制在其自己的命名空间下。 通过设置 Chroot&#xff…

Javaweb之SpringBootWeb案例之 Bean管理的Bean作用域详细的解析

2.2 Bean作用域 在前面我们提到的IOC容器当中&#xff0c;默认bean对象是单例模式(只有一个实例对象)。那么如何设置bean对象为非单例呢&#xff1f;需要设置bean的作用域。 在Spring中支持五种作用域&#xff0c;后三种在web环境才生效&#xff1a; 作用域说明singleton容器…

【前端素材】推荐优质后台管理系统网页Hyper平台模板(附源码)

一、需求分析 1、系统定义 后台管理系统是一种用于管理和控制网站、应用程序或系统的管理界面。它通常被设计用来让网站或应用程序的管理员或运营人员管理内容、用户、数据以及其他相关功能。后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;通常由管理员使…

SLAM运动模型

经典的SLAM模型是由一个运动方程和一个观测方程构成的&#xff0c;如下图所示&#xff1a; 其中&#xff1a;x_k为机器人的状态&#xff0c;z为机器人的观测数据&#xff0c;u_k为控制数据&#xff0c;y_j观测点&#xff0c;w和v分别为运动噪声和观测噪声。f为运动方程&#xf…

解决方案:win11自带的截图工具无反应,快捷键(win+shift+S)同样无法使用

问题描述 截图时某次开始突然无法使用 winshiftS 调用win11自带的“截图工具”截图了&#xff0c;我机器的表现是&#xff1a; 使用该快捷键无法调用截图工具&#xff0c;鼠标旁边会有蓝色小圈圈转一下&#xff0c;但也就是转一下&#xff1b;在搜索框手动搜索 “截图工具” …

递归算法题练习(数的计算、带备忘录的递归、计算函数值)

目录 递归的介绍 递归如何实现 递归和循环的比较 例题: &#xff08;一、斐波那契数列&#xff0c;带备忘录的递归&#xff09; 如果直接使用递归&#xff0c;难以算出结果&#xff0c;需要优化 优化方法&#xff1a;带备忘录的递归 &#xff08;二、数的计算&#xff09…

【Linux进程】进程状态(运行阻塞挂起)

目录 前言 1. 进程状态 2. 运行状态 3. 阻塞状态 4. 挂起状态 5. Linux中具体的状态 总结 前言 在Linux操作系统中&#xff0c;进程状态非常重要&#xff0c;它可以帮助我们了解进程在系统中的运行情况&#xff0c;从而更好地管理和优化系统资源&#xff0c;在Linux系统中&am…

3D城市模型可视化:开启智慧都市探索之旅

随着科技的飞速发展&#xff0c;我们对城市的认知已经不再局限于平面的地图和照片。今天&#xff0c;让我们领略一种全新的城市体验——3D城市模型可视化。这项技术将带领我们走进一个立体、生动的城市世界&#xff0c;感受前所未有的智慧都市魅力。 3D城市模型通过先进的计算机…

Harbor高可用(haproxy和keepalived)

Harbor高可用&#xff08;haproxy和keepalived&#xff09; 文章目录 Harbor高可用&#xff08;haproxy和keepalived&#xff09;1.Harbor高可用集群部署架构1.1 主机初始化1.1.1 设置网卡名和ip地址1.1.2 设置主机名1.1.3 配置镜像源1.1.4 关闭防火墙1.1.5 禁用SELinux1.1.6 设…

Java 下载excel文件

一、背景 微信小程序需要导出excel文件&#xff0c;后端技术Java&#xff0c;前端使用uniapp框架&#xff0c;使用excel模板。 二、excel 报表模板 需要补充的内容是以下标记问号的&#xff0c;其中有个表格&#xff0c;内容是动态添加的 三、Java端代码实现 关键步骤&…

SVPWM

SVPWM SVPWMSVPWM原理产品比较特点来源 SVPWM SVPWM的主要思想是以三相对称正弦波电压供电时三相对称电动机定子理想磁链圆为参考标准&#xff0c;以三相逆变器不同开关模式作适当的切换&#xff0c;从而形成PWM波&#xff0c;以所形成的实际磁链矢量来追踪其准确磁链圆。传统…

如何设置从小程序跳转到其它小程序

​有的商家有多个小程序&#xff0c;希望能够通过一个小程序链接到所有其它小程序&#xff0c;用户可以通过点击跳转链接实现从一个小程序跳转到另一个小程序。要怎么才能实现这样的跳转呢。下面具体介绍。 1. 设置跳转。在小程序管理员后台->分类管理&#xff0c;添加一个…

【开源】JAVA+Vue.js实现天沐瑜伽馆管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 瑜伽课程模块2.3 课程预约模块2.4 系统公告模块2.5 课程评价模块2.6 瑜伽器械模块 三、系统设计3.1 实体类设计3.1.1 瑜伽课程3.1.2 瑜伽课程预约3.1.3 系统公告3.1.4 瑜伽课程评价 3.2 数据库设计3.2.…

C++与 Fluke5500A设备通过GPIB-USB-B通信的经验积累

C与 Fluke5500A设备通过GPIB-USB-B通信的经验积累 以下内容来自&#xff1a;C与 Fluke5500A设备通过GPIB-USB-B通信的经验积累 - JMarcus - 博客园 (cnblogs.com)START 1.需要安装NI-488.2.281&#xff0c;安装好了之后&#xff0c;GPIB-USB-B的驱动就自动安装好了 注意版本…