设计模式-结构型-适配器模式

在软件开发中,随着系统的不断扩展和模块的不断增加,往往会遇到不同模块之间接口不兼容的情况。此时,如果我们能通过某种方式将一个接口转化为另一个接口,那么开发工作将变得更加灵活和高效。适配器模式(Adapter Pattern)正是为了解决这个问题而设计的,它能够让两个不兼容的接口能够协同工作。

本文将深入解析适配器模式的概念、应用场景、实现方法,并通过代码示例帮助大家理解如何在实际开发中使用适配器模式。


1. 适配器模式简介

适配器模式属于结构型模式,它通过将一个类的接口转换为客户端所期待的另一个接口,使得原本接口不兼容的类可以一起工作。

定义

适配器模式(Adapter Pattern)是通过“适配器类”对两个接口进行转换,从而使得不兼容的接口能够正常交互和工作。简单来说,它充当了一个桥梁,使得接口不匹配的类能够协同工作。


2. 适配器模式的结构

适配器模式主要包含以下几个部分:

  • 目标接口(Target):客户端所需要的接口,它是适配器模式的核心。
  • 源接口(Adaptee):需要被适配的现有接口。这个接口与目标接口不兼容,需要通过适配器进行转换。
  • 适配器(Adapter):适配器实现了目标接口,调用源接口的相关方法,以达到兼容的效果。

UML 图示

图像来源

 
  • Client:客户端,调用目标接口的代码。
  • Target:目标接口,客户端期待的接口。
  • Adapter:适配器类,适配源接口(Adaptee)到目标接口(Target)。
  • Adaptee:源接口,原有的不兼容接口。

3. 适配器模式的类型

适配器模式可以分为两种常见的类型,具体选择哪种取决于应用场景:

3.1 类适配器模式(Class Adapter)

类适配器通过继承源类(Adaptee)来实现目标接口(Target)。在类适配器中,适配器通过继承的方式来实现接口的适配。

3.2 对象适配器模式(Object Adapter)

对象适配器通过组合(而非继承)来实现目标接口,适配器将源对象作为成员变量,并通过调用源对象的方法来完成适配。这种方式更加灵活,因为它不依赖于类的继承关系。


4. 适配器模式的应用场景

适配器模式通常用于以下几种情况:

  1. 需要复用现有类的功能,但接口不兼容时: 如果已有的类或者模块接口与当前系统中的接口不兼容,可以使用适配器模式来进行适配。

  2. 系统中多个类需要转换成统一接口时: 如果系统中有多个类,客户端希望统一调用它们的接口,而这些类的接口不同,可以通过适配器模式进行统一适配。

  3. 第三方库的接口与系统不兼容时: 在集成第三方库时,库的接口可能与现有系统的接口不匹配,适配器模式可以帮助进行接口转换。


5. 适配器模式的优缺点

优点

  • 解耦:通过适配器模式,客户端和原有接口之间的耦合度降低,客户端不再依赖于源接口的实现细节。
  • 提高兼容性:适配器模式使得两个不兼容的接口能够协同工作,扩展性好。
  • 代码复用性强:可以将已有类的功能复用到新的接口上,避免重复代码。

缺点

  • 增加系统复杂性:由于引入了适配器类,可能会增加代码的复杂度,导致系统结构变得更加复杂。
  • 性能开销:适配器模式需要额外的对象包装和转换,可能会导致一定的性能开销。

6. 适配器模式的实现

6.1 示例:类适配器模式

假设我们有一个需求,需要将一个旧的类(OldSystem)的接口适配到新的系统接口(TargetSystem)中。我们通过继承的方式来实现适配。

# 目标接口
class TargetSystem:def request(self):pass# 源接口
class OldSystem:def specific_request(self):return "Old system request"# 类适配器:继承源接口,适配成目标接口
class Adapter(TargetSystem, OldSystem):def request(self):# 调用源接口的方法,并将其适配为目标接口return self.specific_request()# 客户端代码
if __name__ == "__main__":target = Adapter()print(target.request())  # 输出:Old system request
解释:
  • TargetSystem 是客户端期望的目标接口。
  • OldSystem 是现有的接口,它的方法是 specific_request,客户端不直接兼容。
  • Adapter 继承了 TargetSystemOldSystem,并实现了目标接口的 request 方法,将其适配为源接口的方法 specific_request

6.2 示例:对象适配器模式

在对象适配器模式中,我们不通过继承,而是通过组合将源对象与目标接口适配。

# 目标接口
class TargetSystem:def request(self):pass# 源接口
class OldSystem:def specific_request(self):return "Old system request"# 对象适配器:通过组合的方式适配
class Adapter(TargetSystem):def __init__(self, old_system: OldSystem):self.old_system = old_system  # 组合OldSystem实例def request(self):# 调用源接口的方法,将其适配为目标接口return self.old_system.specific_request()# 客户端代码
if __name__ == "__main__":old_system = OldSystem()target = Adapter(old_system)print(target.request())  # 输出:Old system request
解释:
  • TargetSystem 是目标接口,客户端期望调用的接口。
  • OldSystem 是已有的源接口,无法直接满足目标接口。
  • Adapter 类通过组合 OldSystem 的实例来实现目标接口。

7. 适配器模式的总结

适配器模式是一个非常实用的设计模式,它通过将不兼容的接口转换为目标接口,帮助我们解决系统中不同模块或类之间接口不一致的问题。无论是类适配器模式还是对象适配器模式,都能够使得不同接口的类能够一起工作,提高代码的复用性、灵活性和扩展性。

适配器模式的核心优势

  • 解决接口不兼容问题。
  • 保持原有系统的可扩展性和复用性。
  • 降低系统之间的耦合度。

适配器模式的应用场景

  • 接口不兼容时需要进行转换。
  • 在软件开发中集成第三方库时,常常需要进行接口适配。
  • 系统需要统一多个接口时,适配器模式非常适用。

希望通过本文的介绍,能够帮助你更好地理解适配器模式,并能够在实际开发中灵活使用它。

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

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

相关文章

Vmware安装centos

用来记录自己安装的过程 一、创建虚拟机安装centos镜像 点击完成后,等待一会会进入centos的系统初始化界面 二、centos初始化配置 三、配置网络 1、虚拟网络编辑器,开启VMnet1、VMnet8的DHCP vmware左上角工具栏,点击【编辑】->【虚拟网…

Unity-Mirror网络框架-从入门到精通之Chat示例

文章目录 前言Chat聊天室Authentication授权ChatAuthenticatorChat示例中的授权流程聊天Chat最后 前言 在现代游戏开发中,网络功能日益成为提升游戏体验的关键组成部分。Mirror是一个用于Unity的开源网络框架,专为多人游戏开发设计。它使得开发者能够轻…

知识问答系统

文章目录 早期的问答系统基于信息检索的问答系统基于知识库的问答系统CommunityQA/FAQ-QA:基于问答对匹配的问答系统Hybrid QA Framework混合问答系统框架早期的问答系统 20世纪六七十年代,早期的NLIDB(Natural Language Interface toData bBase)伴随着人工智能的研发逐步兴起…

第3章:Go语言复合数据类型

第3章:Go语言复合数据类型 1. 数组 1.1 数组声明和初始化 // 方式1:声明固定长度数组 var numbers [5]int // 声明一个包含5个整数的数组,默认零值// 方式2:初始化数组 arr1 : [5]int{1, 2, 3, 4, 5} // 完全初始化// 方式3&…

uniapp-vue3 实现, 一款带有丝滑动画效果的单选框组件,支持微信小程序、H5等多端

采用 uniapp-vue3 实现, 是一款带有丝滑动画效果的单选框组件,提供点状、条状的动画过渡效果,支持多项自定义配置,适配 web、H5、微信小程序(其他平台小程序未测试过,可自行尝试) 可到插件市场下载尝试&…

深度学习GPU服务器推荐:打造高效运算平台

文章来源于百家号:GPU服务器厂家 在深度学习和人工智能领域,一个高性能的GPU服务器是研究和开发工作的关键。今天,我们将为大家推荐一款基于详细硬件配置表的深度学习GPU服务器,它专为高效运算和数据处理而设计。 一、机箱设计 …

2025第1周 | JavaScript中的正则表达式

目录 1. 正则表达式是个什么东东?1.1 怎么定义正则1.2 对象字面量方式1.3 类创建方式 2. 怎么使用2.1 实例方法2.1.1 exec方法2.1.2 test方法 2.2 字符串中的方法2.2.1 match/matchAll2.2.2 replace/replaceAll2.2.3 split2.2.4 search 3. 规则3.1 修饰符3.2 字符类…

大模型LLM-Prompt-OPTIMAL

1 OPTIMAL OPTIMAL 具体每项内容解释如下: Objective Clarity(目标清晰):明确定义任务的最终目标和预期成果。 Purpose Definition(目的定义):阐述任务的目的和它的重要性。 Information Gat…

78、使用爱芯派2_AX630C开发板 3.2T高有效算力 低功耗 支持AI-ISP真黑光实验

基本思想:使用爱心元智最新的版本开发板进行实验 AX630C、AX620Q 都是 620E 这一代 一、参考这个官方教程,先把代码在本地交叉编译完成 https://github.com/AXERA-TECH/ax620e_bsp_sdk 然后在拷贝到620c设备上 root@ax630c:~/ax620e_bsp_sdk/msp/out/arm64_glibc/bin# ./…

C语言 扫雷程序设计

目录 1.main函数 2.菜单打印menu函数 3.游戏game函数 4.宏定义 5.界面初始化 6.打印界面 7.设置雷 8.统计排查坐标周围雷的个数 9.排查雷 10.总代码 test.c代码 game.h代码 game.c代码 结语: 一个简单的扫雷游戏,通过宏定义可以修改行列的…

《高速公路警察模拟器》

一个引人入胜的警察故事在等着你,你可以选择扮演男警官或女警官。公路警察模拟器》拥有休闲和模拟两种游戏模式,将两个世界的精华结合在一起:在身临其境的虚拟环境中自由驾驶和行走,在故事驱动的游戏中解决各种令人兴奋的案件。探…

EasyGBS小知识:如何确保摄像机的网络连接稳定?

在当今数字化时代,视频监控系统已成为保障安全和提高效率的重要工具。然而,摄像机的网络连接稳定性直接关系到监控系统的可靠性和有效性。为了确保视频监控系统能够持续稳定地运行,我们需要从硬件、网络设置、软件与监控以及安装与维护等多个…

微服务-Eureka

Eureka的作用 使用RestTemplate完成远程调用需要被调用者的ip和端口,从而能够发起http请求,但是如果有很多个实例也更加不能有效的处理,而且我们又该如何知道这些实例是否健康呢。所以就有了很多的注册中心比如Eureka、Nacos等等。 服务注…

LabVIEW软件侵权分析与应对

问:如果涉及到LabVIEW软件的仿制或模仿,特别是在功能、界面等方面,如何判断是否构成侵权?该如何应对? 答:LabVIEW软件的侵权问题,尤其是在涉及到仿制或模仿其功能、界面、设计等方面&#xff0…

MATLAB仿真:基于GS算法的经大气湍流畸变涡旋光束波前校正仿真

GS算法流程 GS(Gerchberg-Saxton)相位恢复算法是一种基于傅里叶变换的最速下降算法,可以通过输出平面和输入平面上光束的光强分布计算出光束的相位分布。图1是基于GS算法的涡旋光束畸变波前校正系统框图,在该框图中,已…

数树数(中等难度)

题目: 解题代码: n,qmap(int,input().split())#分别输入层数和路径数量 for i in range(q):sinput()#输入“L”或“R”x1for j in s:if j "L":xx*2-1 #!!!规律else:xx*2print(x)

高效内存管理与调试技巧:深入解析 AddressSanitizer

在现代 C开发中,内存管理是一个至关重要但也容易出错的领域。即使使用了智能指针和其他高效工具,复杂的项目仍可能出现内存泄漏、非法访问等问题。为了解决这些问题,Google 开发了一个强大的工具——AddressSanitizer (ASan)。本文将详细介绍…

Vue3 内置组件之Teleport

文章目录 Vue3 内置组件之Teleport概述用法 Vue3 内置组件之Teleport 概述 Teleport 中文翻译为“瞬间移动”&#xff0c;顾名思义&#xff0c;在Vue3 中 <Teleport> 组件可以将组件中内容移动到指定的目标元素上。 用法 <script setup> import {ref} from &qu…

【我的 PWN 学习手札】IO_FILE 之 FSOP

FSOP&#xff1a;File Stream Oriented Programming 通过劫持 _IO_list_all 指向伪造的 _IO_FILE_plus&#xff0c;进而调用fake IO_FILE 结构体对象中被伪造的vtable指向的恶意函数。 目录 前言 一、glibc-exit函数浅析 二、FSOP 三、Largebin attack FSOP &#xff08;…

函数指针的用法

函數指標一些相關的用法和注意事項。以下將詳細說明&#xff1a; 1. 基本寫法: 這是最常見且明確的寫法&#xff0c;尤其在處理重載函數時非常有用。 void (GirlFriend::*girl2)(QString) &GirlFriend::hungry;void: 指標所指向的函數的回傳型別。(GirlFriend::*): 表示…