设计模式--适配器模式 Adapter Pattern
设计模式--适配器模式 Adapter Pattern
- 适配器模式 Adapter Pattern
- 1.1 基本介绍
- 1.2 工作原理
- 类适配器模式
- 对象适配器模式
- 接口适配器模式
- 小结
适配器模式 Adapter Pattern
1.1 基本介绍
(1)适配器模式将某个类的接口转换成为客户端期望的另一个接口表示,主要的目的是兼容性,让原本应接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper).
(2)适配器模式属于结构型模式
(3)主要分为三类:类适配器模式、对象适配器模式、接口适配器模式
1.2 工作原理
- 适配器模式:将一个类的接口转换成为另一种接口,让原本接口不兼容的类可以兼容。
- 从用户的角度看不到被适配者,是解耦的。
- 用户调用适配器转换出来的目标接口方法,适配器再调用被适配者的相关接口方法。
- 用户收到反馈结果,感觉只是和目标接口交互。
类适配器模式
例子:电脑的电源适配器将(家庭用电)电压220伏特转换为5伏特,然后给电脑供电。
被适配者类:
package com.robin.adapter.classAdapter;// 被适配者类
public class Voltage220V {public int outPut220V(){int srcV = 220;System.out.println("[初始-家庭家用电压]电源电压:"+srcV+"伏特");return srcV;}
}
适配接口:
package com.robin.adapter.classAdapter;// 适配接口
public interface ICpVoltage5V {public int outPut();
}
电脑类:
package com.robin.adapter.classAdapter;public class Computer {public void charge(ICpVoltage5V iCpVoltage5V){int i = iCpVoltage5V.outPut();if (i==5){System.out.println("[电源适配器]电压为5伏特,可以开始充电使用了!");}else{System.out.println("[电源适配器]电压不正常,请检查或者更换电源适配器");}}
}
适配器类:
package com.robin.adapter.classAdapter;// 适配器类
public class CpVoltageAdapter extends Voltage220V implements ICpVoltage5V{@Overridepublic int outPut() {// 因为是继承关系,所以调用其父类的 电源电压输出int src = outPut220V();// 对220V电压进行简单转换int dest = src/44;return dest;}
}
测试客户端类:
package com.robin.adapter.classAdapter;public class Client {public static void main(String[] args) {Computer computer = new Computer();// 通过传入其适配器类的对象来进行充电computer.charge(new CpVoltageAdapter());// [电源适配器]电压为5伏特,可以开始充电使用了!}
}
类适配器模式的优点和缺点:
- 缺点:Java是单继承,但再类适配器模式中,适配器类需要继承被适配的类,失去了灵活性。并且被适配者类的方法都会在适配器类中暴露出来,增加了使用的成本。
- 优点:因为适配器类继承了被适配者类,所以适配器类可以根据需求,灵活的重写被适配者类。
对象适配器模式
对象适配器模式针对上面的类适配器模式进行了一些修改,通过合成复用来代替原本的继承关系。
tip:对象适配器模式是适配器模式中常用的一种。
例子:还是上面的电脑电源的适配器问题,进行修改,将其改为对象适配器模式的。
我们只需要将适配器类中取消继承被适配的类,然后在适配器类中提供一个被适配类的成员变量及构造器即可。
被适配者类:
package com.robin.adapter.objectAdapter;// 被适配者类
public class Voltage220V {public int outPut220V(){int srcV = 220;System.out.println("[初始-家庭家用电压]电源电压:"+srcV+"伏特");return srcV;}
}
适配接口:
package com.robin.adapter.objectAdapter;// 适配接口
public interface ICpVoltage5V {public int outPut();
}
电脑类:
package com.robin.adapter.objectAdapter;public class Computer {public void charge(ICpVoltage5V iCpVoltage5V){int i = iCpVoltage5V.outPut();if (i==5){System.out.println("[电源适配器]电压为5伏特,可以开始充电使用了!");}else{System.out.println("[电源适配器]电压不正常,请检查更换电源适配器");}}
}
适配器类:
package com.robin.adapter.objectAdapter;// 适配器类
public class CpVoltageAdapter implements ICpVoltage5V {// 合成复用 将被适配类聚合到适配器类中private Voltage220V voltage220V = null;// 提供被适配类的构造器public CpVoltageAdapter(Voltage220V voltage220V) {this.voltage220V = voltage220V;}// 重写适配接口中的方法@Overridepublic int outPut() {if (null != voltage220V){int srcV = voltage220V.outPut220V();int dstV = srcV/44;System.out.println("电源电压适配完成,电源电压="+dstV);return dstV;}return -1;}
}
客户端测试类:
package com.robin.adapter.objectAdapter;public class Client {public static void main(String[] args) {System.out.println("对象适配器模式");Computer computer = new Computer();computer.charge(new CpVoltageAdapter(new Voltage220V()));}
}
对象适配器模式与类适配器模式基本一致,只是通过合成复用代替继承,解决了类适配器产生的继承局限问题,使用成本更低更灵活。
接口适配器模式
接口适配器模式的思想:当不需要全部实现接口提供的方法时,可以先设计一个抽象类实现接口,并为该接口中的每个方法提供一个默认实现(空方法体),那么该抽象类的子类可以有选择的覆盖父类的某些方法来实现需求。
接口适配器模式适用于不想使用一个适配接口中所有方法的情况,按照自己的需求来挑选合适的方法自行实现。
比如,你要去旅游了,每个国家插座插孔和电压都不一样,你带了一个万能转换器(比如:wp-933)
然后各国插座如下:
暂且假定该万能转换插孔只提供一个空的插孔,需要你去自定义实现(我例子举得不是很好…有点牵强)
万能插孔适配接口:
package com.robin.adapter.interfaceadpter;// 万能插孔适配接口
public interface AllJacks {// 德国标准public void germanJack();// 欧洲标准public void europeanJack();// 中国,澳大利亚标准public void chinaAndOzJack();// 美国标准public void usaJack();//......
}
万能插孔抽象类实现接口中的所有方法,提供空方法体:
package com.robin.adapter.interfaceadpter;// 抽象类实现万能适配接口,实现全部接口方法,提供空方法体
public abstract class AbsAllJacksAdapter implements AllJacks {// 德国@Overridepublic void germanJack() {}// 欧洲@Overridepublic void europeanJack() {}// 中国和澳大利亚@Overridepublic void chinaAndOzJack() {}// 美国@Overridepublic void usaJack() {}
}
客户端测试:
package com.robin.adapter.interfaceadpter;public class Client {public static void main(String[] args) {// 中国电脑插孔为三孔,方形String srcJack = "[三孔]三方形孔";// 假设我现在旅行去美国AbsAllJacksAdapter absAllJacksAdapter = new AbsAllJacksAdapter(){@Overridepublic void usaJack() {System.out.println("=============使用万能转化器转换=============");// 美国电压为 100-130V,插孔为三孔,两方一圆String destJack = "[三孔]两方一圆孔";System.out.println("[插孔适配完毕]:"+srcJack+"==>"+destJack);}};absAllJacksAdapter.usaJack();}
}
小结
适配器模式的三种方式,也其实就是被适配类,如何被适配器类获取使用的(类=>继承,对象=>合成复用,接口)。Adapter适配器模式的最大作用就是将原本不兼容的接口融合在一起工作。
相关文章:

设计模式--适配器模式 Adapter Pattern
设计模式--适配器模式 Adapter Pattern适配器模式 Adapter Pattern1.1 基本介绍1.2 工作原理类适配器模式对象适配器模式接口适配器模式小结适配器模式 Adapter Pattern 1.1 基本介绍 (1)适配器模式将某个类的接口转换成为客户端期望的另一个接口表示&…...
PVE虚拟机篇-rest api
rest api官方介绍 Proxmox VE API rest api文档 rest api文档 rest api token 调用pve rest api ,有两种认证方式 Ticket Cookie Ticket Cookie的方式是最为推荐的,获取的方式为,通过post请求,发送用户名和密码到pve的server端获取tok…...
2022-2025学年面向中小学生的白名单全国性竞赛活动清单及官网地址链接
**资料来源:爬虫爬取。** 教育部办公厅 工业和信息化部办公厅关于公布 首批特色化示范性软件学院名单的通知 教育部办公厅 工业和信息化部办公厅关于公布首批特色化示范性软件学院名单的通知 - 中华人民共和国教育部政府门户网站 教育部办公厅关于2022-2025学年面向中小学生…...

Python 高级编程之生成器与协程进阶(五)
文章目录一、概述二、生成器1)生成器和迭代器的区别2)生成器创建方式1、通过生成器函数创建2、通过生成器表达式创建3)生成器表达式4)yield关键字5)生成器函数6)return 和 yield 异同7)yield的使…...

Django框架之视图和URL
视图和URL 站点管理页面做好了, 接下来就要做公共访问的页面了.对于Django的设计框架MVT. 用户在URL中请求的是视图.视图接收请求后进行处理.并将处理的结果返回给请求者.使用视图时需要进行两步操作 1.定义视图2.配置URLconf 1. 定义视图 视图就是一个Python函数,…...

Python 的Tkinter包系列之七:好例子补充2
Python 的Tkinter包系列之七:好例子补充2 英汉字典(使用文本文件记录英语单词和解释)、简单的通信录(使用SQLite数据库记录人员信息) 一、tkinter编写英汉字典 先看效果图: 词典文件是一个文本文件&…...
每日一练-等差数列
等差数列🍀题目描述🌿解题思路🌸Python源码📧Summary📆Date: 2023年2月10日 🎬Author: 小 y 同 学 📃Classify: 蓝桥杯每日一练 🔖Language: Python 🍀题目描述 题意 …...

使用动态参数构建CUDA图
文章目录使用动态参数构建CUDA图使用显式 API 调用构建 CUDA 图使用流捕获构建 CUDA 图组合方法执行结果总结使用动态参数构建CUDA图 自从在 CUDA 10 以来,CUDA Graphs 已被用于各种应用程序。 上图将一组 CUDA 内核和其他 CUDA 操作组合在一起,并使用指…...
在Fortran中调用Python教程
前言Python是机器学习领域不断增长的通用语言。拥有一些非常棒的工具包,比如scikit-learn,tensorflow和pytorch。气候模式通常是使用Fortran实现的。那么我们应该将基于Python的机器学习迁移到Fortran模型中吗?数据科学领域可能会利用HTTP AP…...

04-PS人像磨皮方法
1.高斯模糊磨皮 这种方法的原理就是建立一个将原图高斯模糊后图层, 然后用蒙版加画笔或者历史画笔工具将需要磨皮的地方涂抹出来, 通过图层透明度, 画笔流量等参数来控制磨皮程度 1.新建图层(命名为了高斯模糊磨皮), 混合模式设置为正常, 然后选择高斯模糊, 模糊数值设置到看…...

nginx反向代理+负载均衡上传webshell重难点+apache漏洞
nginx反向代理 nginx 负载均衡 负载均衡的策略 1、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB… upstream mysvr { server 192.168.137.131; server 192.168.137.136; }2、weight:跟据配置…...
transition组件的使用
<template><button click"flag !flag">切换</button><transition name"fade"><div v-if"flag" class"box"></div></transition> </template><script setup lang"ts"&g…...

多行文本在块元素中垂直居中
单行文本垂直居中对齐 在块元素中,让单行文本居中,可以使用line-height等于块元素的高,即可让该单行文本垂直居中对齐。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><me…...
在 WebAssembly 中使用 C/C++ 和 libbpf 编写 eBPF 程序
作者:于桐,郑昱笙 eBPF(extended Berkeley Packet Filter)是一种高性能的内核虚拟机,可以运行在内核空间中,用来收集系统和网络信息。随着计算机技术的不断发展,eBPF 的功能日益强大,…...
leveldb源码解析六——compact
compact分为manual_compaction、minor_compaction、major_compaction,统一由MaybeScheduleCompaction触发: void DBImpl::MaybeScheduleCompaction() {mutex_.AssertHeld();if (background_compaction_scheduled_) {// Already scheduled} else if (shu…...

数据结构(二):单向链表、双向链表
数据结构(二)一、什么是链表1.数组的缺点2.链表的优点3.链表的缺点4.链表和数组的区别二、封装单向链表1. append方法:向尾部插入节点2. toString方法:链表元素转字符串3. insert方法:在任意位置插入数据4.get获取某个…...

COCO物体检测评测方法简介
本文从ap计算到map计算,最后到coco[0.5:0.95:0.05] map的计算,一步一步拆解物体检测指标map的计算方式。 一、ap计算方法 一个数据集有多个类别,对于该数据库有5个gt,算法检测出来10个bbox,对于人这个类别来说检测有…...

记一次上环境获取资源失败的案例
代码结构以及资源位置 测试代码 RestController RequestMapping("/json") public class JsonController {GetMapping("/user/1")public String queryUserInfo() throws Exception {// 如果使用全路径, 必须使用/开头String path JsonController.class.ge…...

实战超详细MySQL8离线安装
在RedHat中,RPM Bundle 方式安装MySQL8。建议一定要用 RPM Bndle 版本安装,包全。官网下载:https://dev.mysql.com/downloads/mysql/1.卸载mariadb,会与MySQL安装冲突。rpm -qa | grep mariadb 查看有无mariadb如果有࿰…...
依赖倒置原则|SOLID as a rock
文章目录 意图动机:违反依赖倒置原则解决方案:C++中依赖倒置原则的例子依赖倒置原则的优点1、可复用性2、可维护性在C++中用好DIP的标准总结本文是关于 SOLID as Rock 设计原则系列的五部分中的 最后一部分。 SOLID 设计原则侧重于开发 易于维护、可重用和可扩展的软件。 在…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...