Python设计模式 - 适配器模式

定义

适配器模式(Adapter Pattern)是一种结构型设计模式,它用于将一个类的接口转换为客户端所期待的另一个接口。
注:在适配器模式定义中所提及的接口是指广义的接口,它可以表示一个方法或者一组方法的集合。

结构

适配器模式可分为对象适配器模式和类适配器模式两种。在对象适配器模式中,适配器与适配者之间是关联关系;在类适配器模式中,适配器与适配者之间是继承关系。

对象适配器模式:
在这里插入图片描述

类适配器模式:
在这里插入图片描述

  • 目标抽象类(Target): 客户端希望使用的抽象类。
  • 适配者类(Adaptee): 需要适配的具体类。
  • 适配器类(Adapter): 作为一个转换器,对Adaptee和Target进行适配。

应用场景

  1. 复用现有代码:当你有现有的第三方库或遗留代码,这些代码与新的系统接口不兼容时,使用适配器模式可以使它们能够共同工作,而无需修改现有的代码。例如,旧的数据库访问类或旧的消息队列系统,通过适配器模式将它们与新的系统进行兼容。
  2. 多种外部系统对接:在系统需要与多个外部系统进行对接时,不同的外部系统可能会有不同的接口和协议。适配器模式可以帮助将这些不同的接口转换为统一的接口,从而简化集成工作。比如,可以将不同支付网关(如支付宝、微信支付、PayPal等)整合到统一的支付接口中,或将不同操作系统上的图像处理库通过适配器封装为统一接口。
  3. 当系统或接口升级时,新接口可能与旧系统不兼容。适配器模式可以将新接口转换为旧接口的形式,确保旧系统正常运行,无需大规模修改代码。例如,第三方API更新时,适配器可以将新接口转化为旧的调用方式,从而保持兼容性。

优缺点

优点:

  1. 解耦:适配器模式使得客户端和具体的实现类解耦。客户端只与适配器交互,而不直接依赖于具体的类实现,这样客户端无需关心具体实现的细节。
  2. 代码复用性高:通过使用适配器,可以将旧的或第三方的代码与新的系统无缝对接,避免重复开发。
  3. 易于扩展:通过引入新的适配器类,可以快速支持新的接口或协议,而不需要修改现有的代码。

缺点:

  1. 增加系统复杂性:适配器模式通过引入额外的适配器类来实现接口转换,这会使系统的结构更加复杂。在需要多个适配器时,会增加类的数量和相互关系,特别是当适配器层次过多时,可能会导致系统的维护变得更加困难。

代码示例

对象适配器模式

# 目标抽象类
class Payment:def pay(self, amount):pass# 支付宝支付类
class Alipay:def alipay_payment(self, amount):print(f"支付{amount}元,通过支付宝完成支付。")# 微信支付类
class WeChatPay:def wechat_payment(self, amount):print(f"支付{amount}元,通过微信支付完成支付。")# 支付宝适配器类
class AlipayAdapter(Payment):def __init__(self):self.alipay = Alipay()def pay(self, amount):self.alipay.alipay_payment(amount)# 微信支付适配器类
class WeChatPayAdapter(Payment):def __init__(self):self.wechat_pay = WeChatPay()def pay(self, amount):self.wechat_pay.wechat_payment(amount)# 客户端通过适配器来选择支付方式
alipay_adapter = AlipayAdapter()
wechat_adapter = WeChatPayAdapter()alipay_adapter.pay(100)  # 支付100元,通过支付宝
wechat_adapter.pay(200)  # 支付200元,通过微信支付

类适配器模式

# 支付宝适配器类(类适配器)
class AlipayAdapter(Alipay, Payment):def pay(self, amount):# 调用Alipay类的支付方法self.alipay_payment(amount)# 微信支付适配器类(类适配器)
class WeChatPayAdapter(WeChatPay, Payment):def pay(self, amount):# 调用WeChatPay类的支付方法self.wechat_payment(amount)# 客户端通过适配器来选择支付方式
alipay_adapter = AlipayAdapter()
wechat_adapter = WeChatPayAdapter()alipay_adapter.pay(100)  # 支付100元,通过支付宝
wechat_adapter.pay(200)  # 支付200元,通过微信支付

对象适配器模式和类适配器模式的比较

  1. 在类适配器模式中,由于适配器类是适配者类的子类,因此可以在适配器类中重写一些适配者的方法,使得适配器的灵活性更强。而在对象适配器模式中,适配器通过组合适配者类实现功能,要修改适配者的方法则需要通过委托和包装,操作上相对复杂。
  2. 在对象适配器模式中,一个对象适配器可以把多个不同的适配者适配到同一个目标。而在类适配器模式中,虽然可以通过继承多个适配者来实现,但这样会使类结构变得更加复杂,难以维护。
  3. 对象适配器模式 更适合需要高灵活性、能够适配多个不同对象或者无需修改适配者的场景。类适配器模式 适用于适配单一适配者并且对性能和实现简单性有较高要求的场景。

参考

《设计模式的艺术》

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

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

相关文章

【前端工程化】

目录 前端工程户核心技术之模块化前端模块化的进化过程commonjs规范介绍commonjs规范示例commonjs模块打包 amd规范、cmd规范前端工程化关键技术之npmwebpack原理 前端工程户核心技术之模块化 前端模块化是一种标准,不是实现。commonjs是前端模块化的标准&#xff…

关于CNN,RNN,GAN,GNN,DQN,Transformer,LSTM,DBN你了解多少

以下是神经网络中常见的几种模型的简要介绍: 1. ​CNN (Convolutional Neural Network, 卷积神经网络) ​用途: 主要用于图像处理和计算机视觉任务。​特点: 通过卷积核提取局部特征,具有平移不变性,能够有效处理高维数据(如图像…

T113-i开发板的休眠与RTC定时唤醒指南

​​在嵌入式系统设计中,休眠与唤醒技术是优化电源管理、延长设备续航的关键。飞凌嵌入式基于全志T113-i处理器开发设计的OK113i-S开发板提供了两种休眠模式:freeze和mem,以满足不同应用场景下的功耗与恢复速度需求。本文将详细介绍如何让OK1…

SpringBoot项目实战(初级)

目录 一、数据库搭建 二、代码开发 1.pom.xml 2.thymeleaf模块处理的配置类 3.application配置文件 4.配置(在启动类中) 5.编写数据层 ②编写dao层 ③编写service层 接口 实现类 注意 补充(注入的3个注解) 1.AutoWir…

高性能网络SIG双月动态:加速 SMC eBPF 透明替换特性上游化进程,并与上游深度研讨新特性

01、整体进展 本次双月报总结了 SIG 在 1 月和 2 月的工作进展,工作聚焦在 ANCK CVE 和稳定性问题修复,以及上游 SMC eBPF 透明替换特性推进和多个话题讨论上。 本月关键进展: 1. 推进 SMC eBPF 透明替换特性上游化,更新至 V7&…

某视频的解密下载

下面讲一下怎么爬取视频,这个还是比小白的稍微有一点绕的 首先打开网址:aHR0cDovL3d3dy5wZWFydmlkZW8uY29tL3BvcHVsYXJfNA 首页 看一下: 有一个标题和一个href,href只是一个片段,待会肯定要拼接, 先找一…

C++继承机制:从基础到避坑详细解说

目录 1.继承的概念及定义 1.1继承的概念 1.2 继承定义 1.2.1定义格式 1.2.2继承关系和访问限定符 1.2.3继承基类成员访问方式的变化 总结: 2.基类和派生类对象赋值转换 3.继承中的作用域 4.派生类的默认成员函数 ​编辑 默认构造与传参构造 拷贝构造&am…

测试基础入门

文章目录 软件测试基础1.1软件测试概述什么是软件测试什么是软件需求说明书软件测试的原则测试用例的设计测试用例设计的基本原则软件测试分类软件缺陷的定义 2.1软件开发模型软件开发模型概述大爆炸模型(边写边改)软件开发生命周期模型--螺旋模型软件开…

022-spdlog

spdlog 以下是从原理到代码实现的全方位spdlog技术调研结果,结合核心架构、优化策略和完整代码示例: 一、核心架构设计原理 spdlog三级架构 (图示说明:spdlog采用三级结构实现日志系统解耦) Registry管理中枢 全局…

STM32时钟树

时钟树 时钟树就是STM32中用来产生和配置时钟,并且把配置好的时钟发送到各个外设的系统,时钟是所有外设运行的基础,所以时钟也是最先需要配置的东西,在程序中主函数之前还会执行一个SystemClock_Config()函数,这个函数…

【第22节】windows网络编程模型(WSAAsyncSelect模型)

目录 引言 一、WSAAsyncSelect模型概述 二、WSAAsyncSelect模型流程 2.1 自定义消息 2.2 创建窗口例程 2.3 初始化套接字 2.4 注册网络事件 2.5 绑定和监听 2.6 消息循环 三、完整示例代码 引言 在网络编程的广袤天地中,高效处理网络事件是构建稳定应用的…

利用Dify编制用户问题意图识别和规范化回复

继上一篇文章,成功完成Dify本地部署后,主要做了一些workflow和Agent的应用实现,整体感觉dify在工作流可视化编排方面非常好,即使部分功能无法实现,也可以通过代码执行模块或者自定义工具来实现(后续再具体分…

双核锁步技术在汽车芯片软错误防护中的应用详解

摘要 本文深入探讨了双核锁步技术在保障汽车芯片安全性中的应用。文章首先分析了国产车规芯片在高安全可靠领域面临的软错误难点及攻克方向,然后详细介绍了双核锁步技术的基本原理及其在汽车芯片防软错误的重要性。通过对比国内外多家厂商的芯片技术,分析…

Lustre 语言的 Rust 生成相关的工作

目前 Lustre V6 编译器支持编译生成的语言为C语言。但也注意到,以 Rust 语言为生成目标语言,也存在若干相关工作。 rustre(elegaanz) 该项工作为 Lustre v6 语言的解析器,使用 Rust 语言实现。生成 Lustre AST。 项…

Java 之「单调栈」:从入门到实战

Java 单调栈:从入门到实战 文章目录 Java 单调栈:从入门到实战引言什么是单调栈?单调递增栈单调递减栈 单调栈的应用场景Java 实现单调栈代码示例:下一个更大元素代码解析 单调栈的优势实战应用:股票价格跨度代码示例代…

【Golang】defer与recover的组合使用

在Go语言中,defer和recover是两个关键特性,通常结合使用以处理资源管理和异常恢复。以下是它们的核心应用场景及使用示例: 1. defer 的应用场景 defer用于延迟执行函数调用,确保在函数退出前执行特定操作。主要用途包括&#xff…

CSS 中flex - grow、flex - shrink和flex - basis属性的含义及它们在弹性盒布局中的协同作用。

大白话CSS 中flex - grow、flex - shrink和flex - basis属性的含义及它们在弹性盒布局中的协同作用。 在 CSS 的弹性盒布局(Flexbox)里,flex-grow、flex-shrink 和 flex-basis 这三个属性对弹性元素的尺寸和伸缩性起着关键作用。下面为你详细…

OpenGL ES ->乒乓缓冲,计算只用两个帧缓冲对象(Frame Buffer Object)+叠加多个滤镜作用后的Bitmap

乒乓缓冲核心思想 不使用乒乓缓冲,如果要每个滤镜作用下的绘制内容,也就是这个滤镜作用下的帧缓冲,需要创建一个Frame Buffer Object加上对应的Frame Buffer Object Texture使用乒乓缓冲,只用两个Frame Buffer Object加上对应的F…

【HarmonyOS NEXT】关键资产存储开发案例

在 iOS 开发中 Keychain 是一个非常安全的存储系统,用于保存敏感信息,如密码、证书、密钥等。与文件系统不同,Keychain 提供了更高的安全性,因为它对数据进行了加密,并且只有经过授权的应用程序才能访问存储的数据。那…

ccfcsp1901线性分类器

//线性分类器 #include<iostream> using namespace std; int main(){int n,m;cin>>n>>m;int x[1000],y[1000];char z[1000];for(int i0;i<n;i){cin>>x[i]>>y[i];cin>>z[i];}int a[20],b[20],c[20];for(int i0;i<m;i){cin>>a[i…