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

设计模式大全

1. 策略模式

什么是策略模式?

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互换。策略模式使得算法可以独立于使用它的客户端而变化。通过使用策略模式,可以在运行时选择不同的算法,而无需修改上下文代码。

策略模式的组成部分

策略模式主要由以下几个部分组成:

  1. 策略接口(Strategy Interface):定义了所有支持的算法的公共接口。
  2. 具体策略(Concrete Strategy):实现了策略接口的具体算法。
  3. 上下文(Context):维护一个对策略对象的引用,并在需要时调用策略对象的方法。

策略模式的优点

  1. 开闭原则:可以在不修改现有代码的情况下引入新的算法,符合开闭原则(OCP)。
  2. 避免条件语句:通过使用策略模式,可以避免在客户端代码中使用大量的条件语句来选择不同的算法。
  3. 提高灵活性:可以在运行时选择不同的算法,提高了代码的灵活性和可扩展性。

策略模式的缺点

  1. 增加类的数量:每个具体策略都需要一个类,这可能会增加类的数量,导致代码复杂性增加。
  2. 客户端必须知道所有策略:客户端必须知道所有的策略类,并自行决定使用哪一个策略,这增加了客户端的复杂性。

策略模式的示例

假设我们有一个支付系统,支持多种支付方式(如信用卡支付、PayPal 支付和比特币支付)。我们可以使用策略模式来实现不同的支付方式。

在这里插入图片描述

from abc import ABC, abstractmethodclass PaymentStrategy(ABC):@abstractmethoddef pay(self, amount):passclass CreditCardPayment(PaymentStrategy):def __init__(self, card_number, card_expiry, card_cvv):self.card_number = card_numberself.card_expiry = card_expiryself.card_cvv = card_cvvdef pay(self, amount):print(f"Paying {amount} using Credit Card ending with {self.card_number[-4:]}")class PayPalPayment(PaymentStrategy):def __init__(self, email):self.email = emaildef pay(self, amount):print(f"Paying {amount} using PayPal account {self.email}")class BitcoinPayment(PaymentStrategy):def __init__(self, wallet_address):self.wallet_address = wallet_addressdef pay(self, amount):print(f"Paying {amount} using Bitcoin wallet {self.wallet_address}")class PaymentContext:def __init__(self, strategy: PaymentStrategy):self.strategy = strategydef set_strategy(self, strategy: PaymentStrategy):self.strategy = strategydef pay(self, amount):self.strategy.pay(amount)if __name__ == "__main__":# 使用信用卡支付credit_card_payment = CreditCardPayment("1234567890123456", "12/23", "123")context = PaymentContext(credit_card_payment)context.pay(100)# 切换到 PayPal 支付paypal_payment = PayPalPayment("user@example.com")context.set_strategy(paypal_payment)context.pay(200)# 切换到比特币支付bitcoin_payment = BitcoinPayment("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa")context.set_strategy(bitcoin_payment)context.pay(300)# 运行结果
# Paying 100 using Credit Card ending with 3456
# Paying 200 using PayPal account user@example.com
# Paying 300 using Bitcoin wallet 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa

2. 代理模式

什么是代理模式?

代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理,以控制对这个对象的访问。代理模式可以用于延迟加载、访问控制、日志记录等场景。通过使用代理模式,可以在不修改原始对象的情况下,添加额外的功能或控制。

代理模式的组成部分

  1. 接口(Interface):定义了代理类和实际类的公共接口。
  2. 实际类(Real Subject):实现了接口,包含了实际的业务逻辑。
  3. 代理类(Proxy):实现了接口,控制对实际类的访问,并可以在访问实际类之前或之后添加额外的功能。

代理模式的优点

  1. 控制访问:代理模式可以控制对实际对象的访问,例如通过权限控制来限制某些用户的访问。
  2. 延迟加载:代理模式可以延迟实际对象的创建和初始化,直到真正需要使用它时才进行加载,从而提高性能。
  3. 日志记录:代理模式可以在访问实际对象之前或之后添加日志记录功能,方便调试和监控。

代理模式的缺点

  1. 增加复杂性:代理模式引入了额外的代理类,增加了系统的复杂性。
  2. 性能开销:代理模式可能会增加额外的性能开销,特别是在代理类中添加了复杂的逻辑时。

代理模式的示例

假设我们有一个图像查看器应用程序,它可以加载和显示图像。为了提高性能,我们可以使用代理模式来延迟加载图像,直到真正需要显示图像时才进行加载。

在这里插入图片描述

from abc import ABC, abstractmethodclass Image(ABC):@abstractmethoddef display(self):passclass RealImage(Image):def __init__(self, filename):self.filename = filenameself.load_image_from_disk()def load_image_from_disk(self):print(f"Loading image {self.filename} from disk...")def display(self):print(f"Displaying image {self.filename}")class ProxyImage(Image):def __init__(self, filename):self.filename = filenameself.real_image = Nonedef display(self):if self.real_image is None:self.real_image = RealImage(self.filename)self.real_image.display()if __name__ == "__main__":# 创建代理图像对象proxy_image = ProxyImage("test_image.jpg")# 图像尚未加载print("Image not loaded yet.")# 显示图像,触发图像加载proxy_image.display()# 再次显示图像,不会再次加载proxy_image.display()# 运行结果:
# Image not loaded yet.
# Loading image test_image.jpg from disk...
# Displaying image test_image.jpg
# Displaying image test_image.jpg
http://www.lryc.cn/news/462221.html

相关文章:

  • redis IO多路复用机制
  • Oracle漏洞修复 19.3 补丁包 升级为19.22
  • Q2=10 and Q2=1--PLB(Fig.4)
  • sd卡挂载返回FR_NOT_READY等错误
  • 推荐一款超级实用的浏览器扩展程序!实时翻译网页,支持多种语言(带私活源码)
  • manjaro kde 24 应该如何设置才能上网(2024-10-13亲测)
  • 2024软件测试面试大全(答案+文档)
  • unity动态批处理
  • faust,一个神奇的 Python 库!
  • electron本地OCR实现
  • RK3588的demo板学习
  • 基于springboot驾校管理系统
  • 关于Vue脚手架
  • MySQL 指定字段排序
  • Mysql—高可用集群MHA
  • MeshGS: Adaptive Mesh-Aligned GaussianSplatting for High-Quality Rendering 论文解读
  • JDK-23与JavaFX的安装
  • LeetCode讲解篇之2266. 统计打字方案数
  • 2025推荐选题|基于MVC的农业病虫害防治平台的设计与实现
  • Vue 3 的不同版本总结
  • 在wpf 中 用mvvm 的方式 绑定 鼠标事件
  • TELEDYNE DALSA相机连接编码器
  • 每天一个数据分析题(五百零八)- 机器学习模型
  • leetcode栈与队列(一)-有效的括号
  • 鸿蒙NEXT开发-知乎评论小案例(基于最新api12稳定版)
  • 重学SpringBoot3-集成Redis(十一)之地理位置数据存储
  • Docker-compose 单节点管理、consul 注册中心、registrator、template
  • 制药企业MES与TMS的数据库改造如何兼顾安全与效率双提升
  • Spring Boot比Spring多哪些注解
  • 985研一学习日记 - 2024.10.17