一、模式定义与核心思想

适配器模式(Adapter Pattern) 是一种结构型设计模式,它通过创建一个中间层(适配器),将不兼容的接口转换为客户端期望的接口。就像现实中的电源适配器,让不同国家的插头都能在同一个插座上工作。

二、模式结构解析

# 目标接口:客户端期望的接口
class Target:def request(self):"""标准请求方法"""raise NotImplementedError# 被适配者:已有的不兼容实现
class Adaptee:def specific_request(self):"""特殊请求方法,与目标接口不兼容"""return "特殊请求结果"# 适配器:核心转换逻辑
class Adapter(Target):def __init__(self, adaptee):self.adaptee = adaptee  # 持有被适配对象的引用def request(self):"""将标准请求转换为特殊请求"""return f"适配器转换: {self.adaptee.specific_request()}"

三、实际应用场景演示

场景:集成旧版日志系统

# 旧日志系统(不兼容的被适配者)
class LegacyLogger:def log_to_file(self, message):"""仅支持文件日志"""with open("app.log", "a") as f:f.write(f"[FILE] {message}\n")# 新日志接口规范
class NewLogger(Target):def log(self, level, message):"""标准日志接口"""raise NotImplementedError# 日志适配器实现
class LoggerAdapter(NewLogger):def __init__(self, legacy_logger):self.legacy_logger = legacy_loggerdef log(self, level, message):"""将新接口转换为旧接口调用"""formatted_msg = f"[{level.upper()}] {message}"self.legacy_logger.log_to_file(formatted_msg)# 客户端使用
if __name__ == "__main__":legacy = LegacyLogger()adapter = LoggerAdapter(legacy)# 客户端调用新接口adapter.log("error", "系统崩溃了!")  # 实际调用旧日志系统

四、模式变体与实现方式

1. 类适配器(通过多重继承)

class ClassAdapter(Target, Adaptee):def request(self):"""直接继承被适配者并实现目标接口"""return f"类适配器转换: {self.specific_request()}"

2. 对象适配器(通过组合)

class ObjectAdapter(Target):def __init__(self, adaptee):self.adaptee = adaptee  # 组合方式持有被适配对象def request(self):return f"对象适配器转换: {self.adaptee.specific_request()}"

五、应用场景深度解析

  1. 系统集成:整合老旧系统与新架构

    • 银行系统集成不同时期的交易模块
    • 电商系统对接多个物流供应商API
  2. 第三方库适配:统一不同库的接口

    # 不同支付网关适配示例
    class PaymentAdapter(Target):def __init__(self, payment_gateway):self.gateway = payment_gatewaydef request(self):if "Alipay" in str(type(self.gateway)):return self._alipay_adapter()elif "WeChat" in str(type(self.gateway)):return self._wechat_adapter()def _alipay_adapter(self):# 转换支付宝接口passdef _wechat_adapter(self):# 转换微信支付接口pass
    
  3. 接口标准化:统一不同硬件设备的控制接口

    • 智能家居系统中控制不同品牌的智能设备

六、模式优缺点分析

优点缺点
✅ 符合开闭原则(扩展开放,修改关闭)❌ 增加系统复杂度
✅ 提高类复用性❌ 过多适配器可能影响性能
✅ 灵活替换实现方案

七、最佳实践建议

  1. 明确适配边界:只为真正不兼容的接口创建适配器
  2. 保持适配器精简:避免在适配器中添加业务逻辑
  3. 命名规范:建议使用XxxAdapter的命名方式
  4. 文档说明:明确标注适配关系和转换逻辑

八、模式对比

模式核心目的适用场景
适配器模式接口转换接口不兼容但功能相似
装饰器模式动态扩展功能需要透明地添加多个功能
外观模式简化复杂子系统接口提供统一入口的复杂系统

九、总结

适配器模式是解决接口兼容性问题的利器,通过创建中间层实现无缝集成。在Python这种动态语言中,可以更灵活地使用__getattr__等魔法方法实现动态适配。使用时需权衡代码复杂度与实际需求,避免过度设计。

附:完整代码示例可在GitHub仓库查看,包含单元测试和更多实现变体。

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

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

相关文章

微信小程序列表数据上拉加载,下拉刷新

1.上拉加载数据,数据 下一页数据 前面的数据([...this.data.list, ...data.records)2.当用户上拉加载过快时,会不停的调用接口,需要节流阀isLoading3.上拉加载到最后一页的判断,isFinish// pages/list.js…

【树上倍增 LCA DFS 前缀和】P10391 [蓝桥杯 2024 省 A] 零食采购|普及+

本文涉及知识点 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 CDFS 树上倍增 LCA P10391 [蓝桥杯 2024 省 A] 零食采购 题目描述 小蓝准备去星际旅行,出发前想在本星系采购一些零食,星系内有 nnn 颗星球&#x…

PDF发票批量打印工具哪个好?高效打印发票的实用工具推荐

开小超市这几年,每月要打几十张进货发票做账,以前打印时总犯愁:有的发票 PDF 太大,打出来字小得看不清;有的又太窄,白白浪费半张纸。试过手动调整,每张都要改缩放比例,累不说&#x…

4G模块 A7680通过MQTT协议连接到华为云

命令说明 基础AT指令 ATi显示产品的标志信息 ATCIMI查询IMSI ATCICCID从SIM卡读取ICCID ATCGSN查询产品序列号 ATCPIN查询卡状态 ATCSQ查询信号强度 ATCGATT查询当前PS域状态 ATCREG查询GPRS注册状态 ATCEREG查询4G注册状态 ATCGPADDR查询PDP地址 ATCMGF选择短信格式 ATCMGS发…

大模型词表设计与作用解析

几乎所有大型语言模型(LLM)都有自己独立的词表(Vocabulary)。这是模型设计和训练过程中的核心组件之一。以下是关于词表的关键点: 1. 词表的作用 分词基础:词表定义了模型如何将输入文本拆分成基本单元&…

(一)Eshop(异常处理中间件/grpc)

文章目录项目地址一、异常处理1.1 自定异常1.2 自定义异常处理中间件1.3 注册中间件二、grpc服务2.1 创建protos1. 打折的protos2. 设置grpc server3. program配置服务4. docker-compose2.2 CRUD1. 查询2.3 测试1. 发起查询请求三、grpc服务消费3.1 创建client1. 添加服务2. 选…

BLIP、InternVL Series(下)

目录 一、InternVL1.5 1、改进 二、InternVL2 1、渐进式扩展 2、多模态扩展 三、InternVL2.5 1、方法 2、数据优化 四、InternVL3 2、方法 3、训练后处理 4、测试时扩展 五、BLIP-3o 一、InternVL1.5 1、改进 InternVL1.5在InternVL基础上,优化了QLLa…

【数据结构】二维差分数组

题目链接 【模板】二维差分_牛客题霸_牛客网 牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 描述 给定一个 nmnm 的整数矩阵 bb,矩阵的下标从 11 开始记作 bi,jbi,j​。现在需要支持 qq 次操作,第 tt 次…

【JDK内置工具】常用工具和实战指令

作者:唐叔在学习 专栏:唐叔的Java实践 关键词: #JDK工具 #Java性能调优 #JVM调优 #内存泄漏排查 #线程死锁分析 #Java开发工具 #线上问题排查 #Java诊断工具 Hello,大家好,我是爱学习的唐叔。作为Java开发者,JDK内置工…

一站式PDF转Markdown解决方案PDF3MD

简介 什么是 PDF3MD ? PDF3MD 是一个现代化、用户友好的网络应用程序,旨在将 PDF 文档转换为干净、格式化的 Markdown 文本。它提供了高效的转换工具,支持多种文件格式之间的转换。 主要特点 PDF 转 Markdown:能够将 PDF 文档转…

RocketMQ学习系列之——MQ入门概念

一、什么是MQMQ(Message Queue,消息队列)是一种能够实现跨进程消息传输,并且消息缓存符合队列特性的组件。二、MQ的作用异步:消息发送方无需等待消息接收方收到消息,发送方将消息成功发送到 MQ 之后即可无阻…

血条识别功能实现及原理

从零开始学Python图像处理 - 血条识别 从实际问题中能快速的学习特定技能,通过完成一个能自动刷怪的工具,达成快速学习python图像处理和识别。 自动刷怪需要先识别怪物,在游戏中怪物类型很多,同时在移动中形态会一直发生变化&…

网络地址和主机地址之间进行转换的类

#pragma once #include "Common.hpp" // 网络地址和主机地址之间进行转换的类class InetAddr { public:InetAddr(){}InetAddr(struct sockaddr_in &addr) : _addr(addr){// 网络转主机_port ntohs(_addr.sin_port); // 从网络中拿到的!网络序列// _i…

《Python 项目 CI/CD 实战指南:从零构建自动化部署流水线》

🛠《Python 项目 CI/CD 实战指南:从零构建自动化部署流水线》 一、引言:为什么 Python 项目需要 CI/CD? 在现代软件开发中,CI/CD(持续集成 / 持续部署)已成为不可或缺的工程实践。它不仅提升了开发效率,还显著降低了部署风险。对于 Python 项目而言,CI/CD 的价值尤…

AJAX 技术

AJAX全称是 Asynchronous JavaScript and XML ( 异步的JavaScript 和 XML ),使用该技术后,可以实现不刷新整个网页,与服务器进行异步通信并更新部分网页。一)为什么需要AJAX?传统网页在与服务器通信时,需要刷新整个页…

Python爬虫实战:研究NLTK库相关技术

1. 引言 1.1 研究背景与意义 随着互联网的快速发展,网络新闻已成为人们获取信息的主要来源之一。每天产生的海量新闻文本蕴含着丰富的信息和知识,但也给信息获取和分析带来了挑战。如何从大量非结构化的新闻文本中自动提取有价值的信息,识别热点话题和趋势,成为当前自然语…

ARM 学习笔记(二)

参考文献:《ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition》1、MMU 1.1 背景早期的内存是比较小的,一般是几十k,不过相应的程序也是比较小的,这时程序可以直接加载到内存中运行。后来为了支持多个程序的并行&…

Github 贪吃蛇 主页设置

自动化脚本顶部元信息触发条件(on:)作业(jobs:)步骤(steps:)1. 生成 SVG2. 推送到 output 分支Commit & Push在 README 里引用参考:https://github.com/Platane/Platane/tree/master 首先写…

关于Spring RestTemplate

​ 一、概述RestTemplate 是 Spring Framework 提供的一个同步 HTTP 客户端工具,用于简化与 RESTful API 的交互。它封装了底层 HTTP 通信细节,提供了统一的 API 来发送各种 HTTP 请求(GET、POST、PUT、DELETE 等),并自…

异步解决一切问题 |消息队列 |减少嵌套 |hadoop |rabbitmq |postsql

设计准则“为什么要考虑这个问题”The forward logic is only about 10% of your code, everything else is 90%.主流逻辑 10%保障扩容和稳健的代码设计90%同步代码就是绑在一个绳上的蚂蚱异步就是实现了解耦这个异步或许有点类似于--一些分布式数据的处理 设计如何实现的呢?…