设计模式 06 适配器模式
适配器模式(Adapter Pattern)属于结构型模式
概述
结构型模式关注如何将现有的类或对象组织在一起形成更加强大的结构。
在生活中,我们经常遇到这样的一个问题:轻薄笔记本通常只有 type-c 或者 usb-a 接口,没有网口。但日常使用中是往往需要连接网口上网的,这时想到的第一个解决方案,就是去买一个转接头或者扩展坞。它们可以将 type-c 或者 usb-a 转换为其他类型的接口供我们使用,实际上这就是一种适配器模式。
我们常用的充电头,为什么叫电源适配器呢?传统的供电是 220V 交流电,但是手机可能只需要 5V 的电压进行充电,所以虽然现在有电,但是不能直接充。也不可能让电力公司专门为我们提供一个 5V 的直流电使用,这时电源适配器就开始发挥作用了。比如苹果的祖传 5V1A 充电头,实际上就是将 220V 交流电转换为 5V 的直流电进行传输。这样就相当于在 220V 交流电和手机之间,做了一个适配器的角色。
适配器模式分为类适配器和对象适配器。
代码实现
这里以电脑需要转接器连接网线上网为例:
类适配器
1、定义电脑
/*** 电脑* <p>想上网,需要插网线*/
public class Computer {/*** 电脑需要连接上转换器才可以上网** @param adapter 转接器*/public void connect(NetToUsb adapter) {// 上网的具体实现,找一个转接头adapter.connectNetLine();}
}
2、定义网线
/*** 网线*/
public class NetLine {/*** 上网*/public void online(){System.out.println("连接网线上网");}
}
3、定义 usb 转网口转接器
/*** 转接器*/
public interface NetToUsb {/*** 处理请求,usb -> 网线*/void connectNetLine();
}
4、定义类适配器
/*** 类适配器*/
public class ClassAdapter extends NetLine implements NetToUsb {@Overridepublic void connectNetLine() {// 可以上网了super.online();}
}
5、使用适配器连接网线上网
// 电脑
Computer computer = new Computer();
// 转接器已经插上网线
ClassAdapter adapter = new ClassAdapter();
// 电脑连接转接器,成功上网
computer.connect(adapter);
这种实现方式需要占用一个继承位。如果此时 NetToUsb 不是接口而是抽象类的话,由于 Java 不支持多继承,就无法实现了。同时根据合成复用原则,应该更多的通过合成的方式去实现功能。
所以来看看第二种,也是用的比较多的一种模式:对象适配器。
对象适配器
4、定义对象适配器
/*** 对象适配器*/
public class ObjectAdapter implements NetToUsb {/*** 网线*/private NetLine netLine;public ObjectAdapter(NetLine netLine) {this.netLine = netLine;}@Overridepublic void connectNetLine() {// 可以上网了netLine.online();}
}
5、使用适配器连接网线上网
/*** 测试示例*/
public class ObjectAdapterTest {@Testpublic void test() {// 电脑Computer computer = new Computer();// 网线NetLine netLine = new NetLine();// 转接器插上网线ObjectAdapter adapter = new ObjectAdapter(netLine);// 电脑连接转接器,成功上网computer.connect(adapter);}}
这样的方式不会占用继承位,且满足合成复用原则,耦合度更低,也更加灵活,推荐使用。
优缺点
优点
1、可以让任何两个没有关联的类一起运行。
2、提高了类的复用。
3、增加了类的透明度。
4、灵活性好。
缺点
1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
2、由于 Java 至多继承一个类,所以至多只能适配一个类,而且目标类必须是抽象类。
使用场景
有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。
注意事项
适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。
参考
https://www.bilibili.com/video/BV1mc411h719?p=7&vd_source=299f4bc123b19e7d6f66fefd8f124a03
相关文章:
设计模式 06 适配器模式
适配器模式(Adapter Pattern)属于结构型模式 概述 结构型模式关注如何将现有的类或对象组织在一起形成更加强大的结构。 在生活中,我们经常遇到这样的一个问题:轻薄笔记本通常只有 type-c 或者 usb-a 接口,没有网口。…...
UE4/5Niagara粒子特效之Niagara_Particles官方案例:3.3->4.3
目录 3.3 Visibility Tag 左边的发射器: 发射器更新 粒子生成 粒子更新 右边的发射器 和左边发射器不同的地方 3.4 Texture Sampling 发射器更新 粒子生成 粒子更新 4.1Play Audio Per Particle 系统 第三个发射器 发射器更新 粒子生成 粒子更新 第二个…...
数据结构队列的实现
本章介绍数据结构队列的内容,我们会从队列的定义以及使用和OJ题来了解队列,话不多说,我们来实现吧 队列 1。队列的概念及结构 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,…...
Gti的基本介绍和使用方式
Git 是一种分布式版本控制系统, 主要用于管理软件开发过程中的代码变更。其基本概念包括: 仓库 (Repository): Git中存储代码的基本单位,即一个代码库。在仓库中可以存储多个分支、标签、提交记录等。 分支 (Branch): Git中的分支是代码的不同开发方向,…...
剑指Offer 24-反转链表
题目描述:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 解题思路: 这道题做过很多次,还是会…...
小研究 - Java虚拟机即时编译器的一种实现原理
深入分析了 Kaffe虚拟机的 JIT(Just-In-Ti…...
【LeetCode】416.分割等和子集
题目 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 输入:nums [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和 [11] 。 示…...
go vet中的那些检测项
go vet 是 Go 语言自带的一个工具,用于分析 Go 代码中的常见错误和潜在问题。它可以检查代码中可能存在的各种问题,例如: 未使用的变量、函数或包 可疑的函数调用 错误的函数签名 程序中的竞态条件 错误的类型转换等 本文意图指令当前go vet所…...
Qt 自定义菜单、右键菜单
在接触Qt这段时间以来,经常遇到菜单项的问题(右键菜单、托盘菜单、按钮菜单等),QMenu用于菜单栏,上下文菜单,弹出菜单等,利用QMenuQAction就可以达到效果! 右键菜单实现:通过重写contextMenuEv…...
VScode 编辑器报错: ‘HelloWorld‘ is declared but its value is never read.
.vue文件被标识红色波浪线;提示: HelloWorld is declared but its value is never read. 问题原因: 因为vue3已经不支持vetur插件。 1、在扩展里面进行搜索Vetur插件,进行禁用或卸载; 2、在 VScode扩展里面搜索并下载…...
如何使用LLM实现文本自动生成视频
推荐:使用 NSDT场景编辑器 助你快速搭建可二次编辑的3D应用场景 介绍 基于扩散的图像生成模型代表了计算机视觉领域的革命性突破。这些进步由Imagen,DallE和MidJourney等模型开创,展示了文本条件图像生成的卓越功能。有关这些模型内部工作的…...
Rust处理JSON
基本操作 Cargo.toml: [package]name "json"version "0.1.0"edition "2021"# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[dependencies]serde { version "1", features …...
Python如何操作网络爬虫
Python是一种非常强大的编程语言,用于网络爬虫操作也非常方便。Python提供了许多用于构建和操作网络爬虫的库和工具,如BeautifulSoup、Scrapy、Requests等。本文将详细介绍Python如何操作网络爬虫。 一、安装相关库 首先,我们需要安装Python…...
linux文件复制覆盖命令
目录 cp 命令参数2.cp -rf 出现复制不覆盖文件问题3.解决文件复制覆盖提示操作问题,以下四种方式,供大家参考使用。方法1:编写带cp的路径复制覆盖文件方法2:在CP命令前面加一个斜杠\,实现强制覆盖文件方法3:…...
modbus概览
modbus Modbus是Modicon(施耐德)公司于1979年开发的串行通信协议。它最初设计用于公司的可编程逻辑控制器(PLC)。 Modbus是一种开放式协议,支持使用RS232/RS485/RS422协议的串行设备,同时还支持调制解调器…...
KMP算法开荒
文章目录 一 、前言二、 暴力解法三、KMP算法原理3.1 自动子串的指针3.2 跳过多少个字符3.3 next数组 - 暴力3.4 next数组 - 求解 四 KMP实现 一 、前言 字符串匹配 import re print(re.search(www, www.runoob.com).span()) # 在起始位置匹配 print(re.search(com, www.run…...
XXL-JOB(2)
Glue模式 任务以源码的形式去维护调度中心,支持实时编译,无需指定JobHandler。 实际上是继承自JobHandler的java类代码,在执行器中运行,可以使用Resource/Autowire注入执行器里中的其他服务. 在执行器中添加service Service p…...
Linux常用命令_网络命令、关机重启命令
文章目录 1. 网络命令1.1 网络命令: write1.2 网络命令: wall1.3 网络命令: ping1.4 网络命令: ifconfig1.5 网络命令: mail1.6 网络命令: last1.7 网络命令: lastlog1.8 网络命令: traceroute1.9 网络命令: netstat1.10 网络命令: setup1.11 挂载命令 2. 关机重启命令2.1 shut…...
用Cmake build OpenCV后,在VS中查看OpenCV源码的方法(环境VS2022+openCV4.8.0) Part I
用Cmake build OpenCV后,在VS中查看OpenCV源码的方法 Part I 写在最前面,最近这段时间的工作需要用opencv,不仅是调包,还要能够看到opencv的源码。然后就跟着网上的教程实现了一遍,在实现过程中,遇到了不少…...
如何使用Docker搭建ZooKeepe集群
1、拉取镜像 # docker pull zookeeper:3.7.12、创建网络 Docker创建容器时默认采用bridge网络,自行分配ip,不允许自己指定。在实际部署中,需要指定容器ip,不允许其自行分配ip,尤其在搭建集群时。可以通过docker netw…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
