(七)趣学设计模式 之 适配器模式!

在这里插入图片描述

目录

    • 一、 啥是适配器模式?
    • 二、 为什么要用适配器模式?
    • 三、 适配器模式的实现方式
      • 1. 类适配器模式(继承插座 👨‍👩‍👧‍👦)
      • 2. 对象适配器模式(插座转换器 🔌)
      • 3. 接口适配器模式(万能插座 🗜️)
    • 四、 三种适配器的对比
    • 五、 适配器模式的优缺点
    • 六、 适配器模式的应用场景
    • 七、 总结

🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!
🌟了解代理模式请看: (六)趣学设计模式 之 代理模式!

这篇文章带你详细认识一下设计模式中的适配器模式

一、 啥是适配器模式?

想象一下,你买了一个新的电器 💡,但是插头和家里的插座不匹配 😫,怎么办? 这时候就需要一个插座转换器 🔌,把电器的插头转换成家里的插座可以使用的类型 💡。

适配器模式,就是用来解决接口不兼容的问题! 它可以将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 🤝。

简单来说,就是把不兼容的接口转换成兼容的接口!

  • 你想使用一个类,但是它的接口和你需要的接口不一样: 就像你想用一个旧的类库,但是它的接口和你的代码不兼容 😫!
  • 你想让两个接口不兼容的类一起工作: 就像你想让一个美国的插头和一个中国的插座一起工作 🔌!
  • 你想重用一些现有的类,但是它们的接口不符合你的要求: 就像你想用一个旧的算法,但是它的输入输出格式和你的代码不兼容 😫!

二、 为什么要用适配器模式?

用适配器模式,好处多多 👍:

  • 提高类的复用性: 可以将一些现有的类适配成新的接口,方便重用 ♻️!
  • 提高系统的灵活性: 可以动态地选择不同的适配器,使得系统更加灵活 🤸!
  • 符合开闭原则: 可以在不修改现有代码的情况下,增加新的适配器,扩展功能 🆕!
  • 解耦: 将客户端和目标类解耦,降低系统的耦合度 🔗!

三、 适配器模式的实现方式

适配器模式主要分为三种:

  • 类适配器模式: 通过继承来实现适配,就像继承了插座的类 👨‍👩‍👧‍👦!
  • 对象适配器模式: 通过组合来实现适配,就像用一个插座转换器 🔌!
  • 接口适配器模式: 通过实现一个抽象类来实现适配,就像万能插座 🗜️!

1. 类适配器模式(继承插座 👨‍👩‍👧‍👦)

类适配器模式,通过继承来实现适配,就像继承了插座的类,拥有了插座的功能 🔌!

案例:电压适配器(经典案例 ⚡)

假设你有一个 220V 的电源 🔌,但是你需要给一个 5V 的设备充电 📱,怎么办? 这时候就需要一个电压适配器,把 220V 的电压转换成 5V 的电压 ⚡!

代码示例:

// 目标接口:5V 电压
public interface Voltage5V {int output5V(); // 输出 5V 电压
}// 需要适配的类:220V 电压
public class Voltage220V {public int output220V() {int src = 220;System.out.println("我是220V电压");return src;}
}// 适配器类:电压适配器
public class VoltageAdapter extends Voltage220V implements Voltage5V {@Overridepublic int output5V() {// 获取 220V 电压int srcV = output220V();// 转换成 5V 电压int dstV = srcV / 44;return dstV;}
}// 客户端
public class Client {public static void main(String[] args) {VoltageAdapter adapter = new VoltageAdapter(); // 创建适配器对象int voltage = adapter.output5V(); // 获取 5V 电压System.out.println("输出电压为:" + voltage + "V"); // 输出电压}
}

分析:

  • Voltage5V 是目标接口,客户端需要使用 5V 电压。
  • Voltage220V 是需要适配的类,它只能输出 220V 电压。
  • VoltageAdapter 是适配器类,它继承了 Voltage220V 类,并实现了 Voltage5V 接口,将 220V 电压转换成 5V 电压。

输出结果:

我是220V电压
输出电压为:5V

2. 对象适配器模式(插座转换器 🔌)

对象适配器模式,通过组合来实现适配,就像用一个插座转换器,把电器的插头转换成家里的插座可以使用的类型 🔌!

案例:还是电压适配器(对象版⚡)

还是上面的电压适配器的例子,但是这次我们使用对象适配器模式来实现 🚀!

代码示例:

// 目标接口:5V 电压
public interface Voltage5V {int output5V(); // 输出 5V 电压
}// 需要适配的类:220V 电压
public class Voltage220V {public int output220V() {int src = 220;System.out.println("我是220V电压");return src;}
}// 适配器类:电压适配器
public class VoltageAdapter implements Voltage5V {private Voltage220V voltage220V; // 组合 220V 电压对象public VoltageAdapter(Voltage220V voltage220V) {this.voltage220V = voltage220V;}@Overridepublic int output5V() {// 获取 220V 电压int srcV = voltage220V.output220V();// 转换成 5V 电压int dstV = srcV / 44;return dstV;}
}// 客户端
public class Client {public static void main(String[] args) {Voltage220V voltage220V = new Voltage220V(); // 创建 220V 电压对象VoltageAdapter adapter = new VoltageAdapter(voltage220V); // 创建适配器对象int voltage = adapter.output5V(); // 获取 5V 电压System.out.println("输出电压为:" + voltage + "V"); // 输出电压}
}

分析:

  • Voltage5V 是目标接口,客户端需要使用 5V 电压。
  • Voltage220V 是需要适配的类,它只能输出 220V 电压。
  • VoltageAdapter 是适配器类,它组合了 Voltage220V 类,并实现了 Voltage5V 接口,将 220V 电压转换成 5V 电压。

输出结果:

我是220V电压
输出电压为:5V

3. 接口适配器模式(万能插座 🗜️)

接口适配器模式,通过实现一个抽象类来实现适配,就像万能插座,可以兼容各种类型的插头 🗜️!

案例:USB 接口适配器(万能接口 💻)

假设你有一个 USB 设备 💾,但是你的电脑只有 Type-C 接口 💻,怎么办? 这时候就需要一个 USB 接口适配器,把 USB 接口转换成 Type-C 接口 💻!

代码示例:

// 目标接口:USB 接口
public interface Usb {void read(); // 读取数据void write(); // 写入数据void connect(); // 连接设备void disconnect(); // 断开连接
}// 抽象适配器类:USB 适配器
public abstract class UsbAdapter implements Usb {@Overridepublic void read() {// 默认实现,可以不实现}@Overridepublic void write() {// 默认实现,可以不实现}@Overridepublic void connect() {// 默认实现,可以不实现}@Overridepublic void disconnect() {// 默认实现,可以不实现}
}// 需要适配的类:Type-C 设备
public class TypeCDevice extends UsbAdapter {@Overridepublic void read() {System.out.println("Type-C 设备读取数据");}@Overridepublic void write() {System.out.println("Type-C 设备写入数据");}
}// 客户端
public class Client {public static void main(String[] args) {TypeCDevice typeCDevice = new TypeCDevice(); // 创建 Type-C 设备对象typeCDevice.connect(); // 连接设备typeCDevice.read(); // 读取数据typeCDevice.write(); // 写入数据typeCDevice.disconnect(); // 断开连接}
}

分析:

  • Usb 是目标接口,客户端需要使用 USB 接口。
  • UsbAdapter 是抽象适配器类,它实现了 Usb 接口,但是提供了默认实现,子类可以选择性地实现需要的方法。
  • TypeCDevice 是需要适配的类,它继承了 UsbAdapter 类,并实现了 readwrite 方法,实现了 USB 接口的功能。

输出结果:

Type-C 设备读取数据
Type-C 设备写入数据

四、 三种适配器的对比

特性类适配器模式对象适配器模式接口适配器模式
实现方式继承组合抽象类
优点简单易用灵活,可以适配多个类可以选择性地实现接口方法
缺点只能适配一个类,耦合度较高需要持有目标类的对象,增加了对象的数量需要定义抽象类,增加了类的数量
适用场景目标类接口比较稳定,不需要经常修改需要适配多个类,或者目标类接口经常修改只需要使用接口中的部分方法

五、 适配器模式的优缺点

优点:

  • 提高类的复用性 ♻️!
  • 提高系统的灵活性 🤸!
  • 符合开闭原则 🆕!
  • 解耦 🔗!

缺点:

  • 增加了系统的复杂度 😫!
  • 可能会降低性能 🐌!

六、 适配器模式的应用场景

  • 接口转换: 将一个类的接口转换成客户希望的另外一个接口 🔌!
  • 数据转换: 将一种格式的数据转换成另外一种格式的数据 🗂️!
  • 遗留系统集成: 将新的系统和旧的系统集成在一起 🤝!
  • 第三方库集成: 将第三方库集成到你的项目中 📚!

七、 总结

  • 适配器模式就像插座转换器,让不兼容的接口也能愉快玩耍! 🔌
  • 主要分为类适配器模式、对象适配器模式和接口适配器模式三种! 🤸
  • 优点是提高类的复用性、提高系统的灵活性、符合开闭原则、解耦! 👍
  • 缺点是增加复杂度、可能降低性能! 👎
  • 适用于需要解决接口不兼容的问题的场景! 🎯

希望这篇文章能让你彻底理解适配器模式! 💯 祝你学习愉快! 😄
看完请看:(八)趣学设计模式 之 装饰器模式!

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

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

相关文章

【Java基础】Java中new一个对象时,JVM到底做了什么?

Java中new一个对象时,JVM到底做了什么? 在Java编程中,new关键字是我们创建对象的最常用方式。但你是否想过,当你写下new MyClass()时,Java虚拟机(JVM)到底在背后做了哪些工作?今天&…

内网穿透:打破网络限制的利器

目录 深入理解内网穿透 内网与外网的奥秘 内网穿透的原理剖析 总结与展望 在如今这个数字化时代,网络已经成为我们生活和工作中不可或缺的一部分。但你是否遇到过这样的困扰:在家办公时,想要访问公司内部的文件服务器,却因为网…

【汽车ECU电控数据管理篇】HEX文件格式解析篇章

一、HEX格式文件是啥 HEX 文件是 Intel 公司提出的一种按地址排列的数据信息格式,通常用于存储嵌入式系统的二进制代码。它以 ASCII 码的形式记录数据,每一行以冒号开头,包含数据长度、地址、记录类型、数据和校验码等信息。HEX 文件常用于程…

深入理解 CSS pointer-events: none:穿透点击的魔法

一、什么是 pointer-events: none? pointer-events: none 是一个强大的 CSS 属性,它控制元素是否响应鼠标/触摸事件(如点击、悬停、拖拽)。当设置为 none 时,元素会变得“透明”,事件会直接穿透到下方的元…

【AHK】资源管理器自动化办公实例/自动连点设置

此处为一个自动连续点击打开检查的自动化操作案例,没有quicker的鼠键录制,不常用了,做个备份 #MaxThreadsPerHotkey 2 ; 这个是核心!!!!确保可以同时运行多个热键或标签global isRunning : tru…

html css js网页制作成品——HTML+CSS甜品店网页设计(5页)附源码

目录 一、👨‍🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨‍&#x1f…

Springboot使用Milvus的基本操作

Milvus 先得保证数据的正确安装并且正确运行 <dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId> </dependency> <dependency><groupId>io.milvus</groupId><artifactId>milvu…

初阶数据结构(C语言实现)——3顺序表和链表(2)

2.3 数组相关面试题 原地移除数组中所有的元素val&#xff0c;要求时间复杂度为O(N)&#xff0c;空间复杂度为O(1)。OJ链接 力扣OJ链接-移除元素删除排序数组中的重复项。力扣OJ链接-删除有序数组中的重复项合并两个有序数组。力扣OJ链接-合并两个有序数组 2.3.1 移除元素 1…

【力扣】2619. 数组原型对象的最后一个元素——认识原型与原型链

【力扣】2619. 数组原型对象的最后一个元素——认识原型与原型链 文章目录 【力扣】2619. 数组原型对象的最后一个元素——认识原型与原型链题目解决方案概述全局上下文函数上下文事件处理程序构造函数上下文类上下文显式 / 隐式绑定绑定方法和永久 this 上下文 方法 1&#xf…

ubuntu终端指令集 shell编程基础(一)

磁盘指令 连接与查看&#xff1a;磁盘与 Ubuntu 有两种连接方式&#xff1b;使用ls /dev/sd*查看是否连接成功&#xff0c;通过df系列指令查看磁盘使用信息。若 U 盘已挂载&#xff0c;相关操作可能失败&#xff0c;需用umount取消挂载。磁盘操作&#xff1a;使用sudo fdisk 磁…

基于Spark的电商供应链系统的设计与实现

目录 1.研究背景与意义 2、国内外研究现状 3、相关理论与技术 &#xff08;一&#xff09;分布式计算系统Spark &#xff08;二&#xff09;数据仓库Hive &#xff08;三&#xff09;读取服务器本地磁盘的日志数据Flume &#xff08;四&#xff09;分布式消息队列Kafka …

使用TortoiseGit配合BeyondCompare实现在Git仓库中比对二进制文件

使用TortoiseGit的比对工具可以直接右键&#xff0c;点击选择比对和上一版本的变化差异&#xff1a; 但是TortoiseGit只能支持比对纯文本文件的变化差异&#xff0c;如果尝试比对二进制文件&#xff0c;会提示这不是一个有效的文本文件&#xff1a; BeyondCompare可以比对二进制…

BladeX框架接口请求跨域

前端使用代理请求接口&#xff0c;接口可以正常访问。如果换全路径请求就跨域。 除了后端要配置跨域 还需要修改配置文件对OPTIONS请求的限制

Vue.js响应式基础

响应式基础​ API 参考 本页和后面很多页面中都分别包含了选项式 API 和组合式 API 的示例代码。现在你选择的是 组合式 API。你可以使用左侧侧边栏顶部的“API 风格偏好”开关在 API 风格之间切换。 声明响应式状态​ ref()​ 在组合式 API 中,推荐使用 ref() 函数来声明…

选开源CMS建站系统时,插件越多越好吗?

在选择开源CMS建站系统时&#xff0c;插件数量并不是唯一的衡量标准&#xff0c;更不能简单地说“插件越多就越好”&#xff0c;还是需要综合评估来考虑选择结果&#xff0c;以下是有关选择开源CMS系统时对插件数量的考量。 插件数量的优势插件数量可能带来的问题功能丰富性&a…

在VSCode中使用MarsCode AI最新版本详解

如何在VSCode中使用MarsCode AI&#xff1a;最新版本详解与使用场景 在当今快速发展的软件开发领域&#xff0c;人工智能&#xff08;AI&#xff09;技术的应用已经变得越来越普遍。ByteDance推出的MarsCode AI是一款强大的AI编程助手&#xff0c;旨在帮助开发者更高效地编写代…

mac修改docker的daemon.json 镜像文件

1、找到daemon.json文件的位置 docker info 可以看出位置在&#xff1a; /Users/spuer/.docker 2. 进入daemon.json 所在的目录&#xff1a; cd /Users/spuer/.docker3. 查看daemon.json的内容&#xff1a; more daemon.json可以看出&#xff0c;没有配置registry-mirrors&…

5.10 P-Tuning v2:多层级提示编码的微调革新

P-Tuning v2:多层级提示编码的微调革新 一、技术架构解析 #mermaid-svg-4Wy6vkXZi67hY9PZ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-4Wy6vkXZi67hY9PZ .error-icon{fill:#552222;}#mermaid-svg-4Wy6vkXZi67h…

Eclipse 编译项目指南

Eclipse 编译项目指南 引言 Eclipse 是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;广泛用于Java、C/C、Python等多种编程语言的开发。在Eclipse中编译项目是进行软件开发的基础步骤。本文将详细介绍如何在Eclipse中编译项目&#xff0c;包括项目设置…

【大语言模型】【整合版】DeepSeek 模型提示词学习笔记(散装的可以看我之前的学习笔记,这里只是归纳与总结了一下思路,内容和之前发的差不多)

以下是个人笔记的正文内容: 原文在FlowUs知识库上&#xff0c;如下截图。里面内容和这里一样&#xff0c;知识排版好看一点 一、什么是 DeepSeek 1. DeepSeek 简介 DeepSeek 是一家专注于通用人工智能&#xff08;AGI&#xff09;的中国科技公司&#xff0c;主攻大模型研发与…