设计模式 - 结构型模式考点篇:适配器模式(类适配器、对象适配器、接口适配器)

目录

一、适配器模式

一句话概括结构式模式

1.1、适配器模式概述

1.2、案例

1.2.1、类适配器模式实现案例

1.2.2、对象适配器

1.2.3、接口适配器

1.3、优缺点(对象适配器模式)

1.4、应用场景


一、适配器模式


一句话概括结构式模式

教你将类和对象结合再一起形成一个更强大的结构.

1.1、适配器模式概述

将一个类的接口转换成客户希望的另一个接口,使得原本不兼容的接口能一起工作.

比如,如果你使用的是苹果手机,那么就意味着充电器的充电口也是苹果标准的,而你现在只有一个 type-c 插孔的插座能充电,因此就需要一个转换器(一头type-c,另一头 苹果插头),就可以让原本不兼容的 苹果插头 一起工作.

适配器模式包含以下主机角色:

  1. 目标接口:当前客户所期待的接口,它可以是抽象类或者接口(上述的 苹果插头).
  2. 适配者类:是被访问的现存组件库中的接口(上述的 type-c).
  3. 适配器类:是一个转换器,通过继承或引用目标接口,实现适配者类的所有方法,就可以实现转换效果.

适配器模式分为 类适配器模式、对象适配器模式 ,其中类适配器耦合度最高(不符合合成/聚合复用原则),且要求程序员了解现有组件库的内部结构,因此应用较少.

还有一种模式叫 接口适配器模式,是对对象适配器的扩展.

1.2、案例

现有一台电脑,只能读取 SD 卡,而我现在只有一个 TF 卡,因此就需要使用适配器模式. 创建一个读卡器,将 TF 卡中的内容读取出来.

1.2.1、类适配器模式实现案例

类适配器只需要我们继承目标接口,实现适配者接口的所有方法即可.

/*** 目标接口: TF 卡*/
public interface TFCard {/*** 读取 TF 卡* @return*/String readTF();/*** 写入 TF 卡*/void writeTF(String msg);}
/*** 目标接口实现类*/
public class TFCardImpl implements TFCard{@Overridepublic String readTF() {String msg = "tf card readTF: hello!";return msg;}@Overridepublic void writeTF(String msg) {System.out.println("tf card writeTF: hello!");}}
/*** 适配者接口: SD 卡*/
public interface SDCard {/*** 读取 SD 卡* @return*/String readSD();/*** 写入 SD 卡*/void writeSD(String msg);}
/*** 适配者实现类: SD 卡实现类*/
public class SDCardImpl implements SDCard {@Overridepublic String readSD() {String msg = "sd card readTF: hello!";return msg;}@Overridepublic void writeSD(String msg) {System.out.println("sd card writeTF: " + msg);}}
/*** 适配器:SD 兼容 TF*/
public class SDAdapterTF extends TFCardImpl implements SDCard{@Overridepublic String readSD() {System.out.println("adapter read tf card");return readTF();}@Overridepublic void writeSD(String msg) {System.out.println("adapter write tf card");writeTF(msg);}}
/*** 电脑类*/
public class Computer {public String readSD(SDCard sdCard) {if(sdCard == null) {throw new NullPointerException("sd card null");}return sdCard.readSD();}}
    public static void main(String[] args) {//1.创建一个电脑类Computer computer = new Computer();//3.通过适配器从电脑中读取 TF 卡的数据SDAdapterTF adapter = new SDAdapterTF();String msg = computer.readSD(adapter);System.out.println(msg);}

1.2.2、对象适配器

对象适配器,相比于 类适配器,更符合 合成/聚合复用原则(持有新对象的引用,而不是通过继承来达到复用目的).  也就是说,它是通过持有目标接口的引用(tf 卡接口的引用),重写 适配者接口 的所有方法实现的 .  

/*** 目标接口: TF 卡*/
public interface TFCard {/*** 读取 TF 卡* @return*/String readTF();/*** 写入 TF 卡*/void writeTF(String msg);}
/*** 目标接口实现类*/
public class TFCardImpl implements TFCard {@Overridepublic String readTF() {String msg = "tf card readTF: hello!";return msg;}@Overridepublic void writeTF(String msg) {System.out.println("tf card writeTF: hello!");}}

/*** 适配者接口: SD 卡*/
public interface SDCard {/*** 读取 SD 卡* @return*/String readSD();/*** 写入 SD 卡*/void writeSD(String msg);}
/*** 适配者实现类: SD 卡实现类*/
public class SDCardImpl implements SDCard {@Overridepublic String readSD() {String msg = "sd card readTF: hello!";return msg;}@Overridepublic void writeSD(String msg) {System.out.println("sd card writeTF: " + msg);}}
/*** 适配器:SD 兼容 TF*/
public class SDAdapterTF implements SDCard {private TFCard tfCard;public SDAdapterTF(TFCard tfCard) {this.tfCard = tfCard;}@Overridepublic String readSD() {System.out.println("adapter read tf card");return tfCard.readTF();}@Overridepublic void writeSD(String msg) {System.out.println("adapter write tf card");tfCard.writeTF(msg);}}
/*** 电脑类*/
public class Computer {public String readSD(SDCard sdCard) {if(sdCard == null) {throw new NullPointerException("sd card null");}return sdCard.readSD();}}
public class Client {public static void main(String[] args) {//1.创建一个电脑类Computer computer = new Computer();//3.通过适配器从电脑中读取 TF 卡的数据SDAdapterTF adapter = new SDAdapterTF(new TFCardImpl());computer.readSD(adapter);}}

1.2.3、接口适配器

当我们不希望实现一个适配者接口(sd 卡接口)中的所有方法时,可以创建一个抽象类 Adapter,实现所有方法(不用实现方法内容).此时我们只需要继承该抽象类,在重写我们需要的方法即可.

实现前两个适配器中,就一直没有使用 writeSD 方法,因此这里就不实现此方法.

/*** 目标接口: TF 卡*/
public interface TFCard {/*** 读取 TF 卡* @return*/String readTF();/*** 写入 TF 卡*/void writeTF(String msg);}
/*** 目标接口实现类*/
public class TFCardImpl implements TFCard {@Overridepublic String readTF() {String msg = "tf card readTF: hello!";return msg;}@Overridepublic void writeTF(String msg) {System.out.println("tf card writeTF: hello!");}}
/*** 适配者接口: SD 卡*/
public interface SDCard {/*** 读取 SD 卡* @return*/String readSD();/*** 写入 SD 卡*/void writeSD(String msg);}
/*** 适配者实现类: SD 卡实现类*/
public class SDCardImpl implements SDCard {@Overridepublic String readSD() {String msg = "sd card readTF: hello!";return msg;}@Overridepublic void writeSD(String msg) {System.out.println("sd card writeTF: " + msg);}}
public abstract class Adapter implements SDCard {@Overridepublic void writeSD(String msg) {}@Overridepublic String readSD() {return null;}}
public class SDAdapterTF extends Adapter implements SDCard{private TFCard tfCard;public SDAdapterTF(TFCard tfCard) {this.tfCard = tfCard;}@Overridepublic String readSD() {System.out.println("adapter read tf card");return tfCard.readTF();}
}
/*** 电脑类*/
public class Computer {public String readSD(SDCard sdCard) {if(sdCard == null) {throw new NullPointerException("sd card null");}return sdCard.readSD();}}
public class Client {public static void main(String[] args) {//1.创建一个电脑类Computer computer = new Computer();//2.通过适配器从电脑中读取 TF 卡的数据SDAdapterTF sdAdapterTF = new SDAdapterTF(new TFCardImpl());String msg = computer.readSD(sdAdapterTF);System.out.println(msg);}}

1.3、优缺点(对象适配器模式)

优点

1. 适配现有类,且不修改类:在不改变现有类的基础上,实现现有类和目标类的接口的匹配.

2. 符合 合成/聚合 复用原则:持有引用,而不继承.

3. 符合开闭原则:如果引入新的目标接口,只需要在适配器类中进行扩展,不需要修改原代码.

缺点:

增加复杂性:编写适配器类时,要考虑全面,包括适配者和目标类.

1.4、应用场景

1. 以前开发的系统中存在满足当前业务所需要的类,但是接口和当前业务所需接口不一致.

2. 第三方提供的组件,但是组件接口定义和自己要求的接口定义不同.

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

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

相关文章

多线程入门

1 创建线程 下面的程序&#xff0c;我们可以用它来创建一个 POSIX 线程&#xff1a; #include <pthread.h> pthread_create (myThread, attr, start_routine, arg) 在这里&#xff0c;pthread_create 创建一个新的线程&#xff0c;并让它可执行。下面是关于参数的说明…

QT自制软键盘 最完美、最简单、跟自带虚拟键盘一样

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 QT自制软键盘 最完美、最简单、跟自带虚拟键盘一样 Chapter1 QT自制软键盘 最完美、最简单、跟自带虚拟键盘一样一、本自制虚拟键盘特点二、windows打开系统自带软键盘三、让…

3、在docker 容器中安装tomcat

&#xff11;、在服务器上查找tomcat镜像,查看前5条 docker search tomcat --limit 5​​​​​​​ 2、拉取镜像到本地 拉取官方的tomcat到本地 docker pull tomcat:9.0.34-jdk8 3、查看本地镜像 docker images |grep tomcat 4、启动tomcat 服务 使用默认配置 docker ru…

如何选择一个向量数据库:Elastic Cloud 和 Zilliz Cloud 面面观

随着以 Milvus 为代表的向量数据库在 AI 产业界越来越受欢迎&#xff0c;诸如 Elasticsearch 之类的传统数据库和检索系统也开始行动起来&#xff0c;纷纷在快速集成专门的向量检索插件方面展开角逐。 例如&#xff0c;在提供类似插件的传统数据库中&#xff0c;Elasticsearch …

VAE模型(详细推导+实例代码)

文章目录 EM算法思路E步M步直观感觉 GMM模型VAEVAE思想从GMM到VAE公式推导重参数VAE神经网络另一个视角的VAE思想为什么引入encoder为什么要重参数噪声与重建 Discrete VAE 本文会从EM算法&#xff0c;GMM模型一步一步的的推导&#xff0c;在过渡到VAE模型&#xff0c;如果有熟…

棱镜七彩参编!开源领域4项团体标准正式发布

近日&#xff0c;中电标2023年第27号团体标准公告正式发布&#xff0c;《T/CESA 1270.2-2023 信息技术 开源治理 第 2 部分&#xff1a;企业治理评估模型》、《T/CESA 1270.3-2023 信息技术 开源治理 第 3 部分&#xff1a;社区治理框架》、《T/CESA 1270.5-2023 信息技术 开源…

信创办公–基于WPS的EXCEL最佳实践系列 (单元格与行列)

信创办公–基于WPS的EXCEL最佳实践系列 &#xff08;单元格与行列&#xff09; 目录 应用背景操作步骤1、插入和删除行和列2、合并单元格3、调整行高与列宽4、隐藏行与列5、修改单元格对齐和缩进6、更改字体7、使用格式刷8、设置单元格内的文本自动换行9、应用单元格样式10、插…

STM32F4X I2C LM75

STM32F4X I2C LM75 I2C协议讲解I2C接线I2C协议波形I2C起始信号I2C停止信号I2C应答信号I2C寻址I2C地址格式 I2C数据传输 LM75ALM75A介绍LM75A引脚说明LM75A地址LM75A寄存器LM75A I2C协议写配置寄存器读配置寄存器写Tos和Thyst寄存器读Tos Thyst Temp寄存器LM75A温度计算 LM75A例…

力扣(LeetCode)2578. 最小和分割(C++)

哈希集合 请读者思考&#xff0c;num拆分成num1和num2&#xff0c;要使得num1 num2最小&#xff0c;应满足两条性质&#xff1a; num1和num2位数相同&#xff0c;或最多差一位。num1和num2应按数值从小到大在num中取数。 想到统计num的位数&#xff0c;以实现性质1的需要&a…

淘宝天猫商品历史价格API接口

获取淘宝商品历史价格接口的步骤如下&#xff1a; 注册淘宝开放平台&#xff1a;首先在淘宝开放平台上注册一个账号&#xff0c;并进行登录。创建应用&#xff1a;在淘宝开放平台上创建一个应用&#xff0c;并获取该应用的App Key和App Secret&#xff0c;用于后续的接口调用。…

【数据结构】二叉树的链式结构及实现

目录 1. 前置说明 2. 二叉树的遍历 2.1 前序、中序以及后序遍历 2.2 层序遍历 3. 节点个数及高度等 4. 二叉树的创建和销毁 1. 前置说明 在学习二叉树的基本操作前&#xff0c;需先要创建一棵二叉树&#xff0c;然后才能学习其相关的基本操作。由于现在大家对二叉树结构…

区块链技术的飞跃: 2023年的数字革命

随着时代的推进和技术的不断创新&#xff0c;2023年成为区块链技术飞跃发展的一年。区块链&#xff0c;一个曾经只是数字货币领域的技术&#xff0c;现在已经逐渐渗透到各个行业&#xff0c;成为推动数字经济发展的重要力量。在这个数字革命的时代&#xff0c;我们探讨区块链技…

什么是存储服务器?

随着互联网的发展&#xff0c;越来越多的信息会在网络上暴露&#xff0c;所以企业就会更加重视数据&#xff0c;因此更加安全可靠的数据存储服务器受到了大多数人的信赖&#xff0c;今天就让小编带大家了解一下什么是存储服务器吧&#xff01; 存储服务器的含义。存储服务器是…

代理IP端口是什么意思呢?

今天&#xff0c;咱们来聊聊一个小众但很有料的话题——代理IP端口&#xff0c;它可是你纵横互联网世界的好搭子哦&#xff01; 首先&#xff0c;我们得先弄明白&#xff0c;代理IP端口是个啥? 代理IP端口就像是通往网络世界的门票&#xff0c;是你和代理服务器之间的桥梁。…

使用注解新开事务 @Transactional

使用注解新开事务 Transactional(propagation Propagation.REQUIRES_NEW)

使用Perl脚本编写爬虫程序的一些技术问题解答

网络爬虫是一种强大的工具&#xff0c;用于从互联网上收集和提取数据。Perl 作为一种功能强大的脚本语言&#xff0c;提供了丰富的工具和库&#xff0c;使得编写的爬虫程序变得简单而灵活。在使用的过程中大家会遇到一些问题&#xff0c;本文将通过问答方式&#xff0c;解答一些…

Jetson Orin NX 开发指南(6): VINS-Fusion-gpu 的编译和运行

一、前言 由于 Jetson 系列的开发板 CPU 性能不是很好&#xff0c;因此在处理图像数据时往往需要 GPU 加速&#xff0c;而 VINS-Fusion 是针对同步定位与建图&#xff08;SLAM&#xff09;问题中十分出色的视觉算法&#xff0c;但是其在图像处理过程中资源消耗较大&#xff0c…

执行make menuconfig问题的解决

执行make menuconfig 出现问题 在终端输入以下命令执行。 make menuconfig在终端输入上面命令执行时&#xff0c;没有成功运行&#xff0c;出现了如下的问题。 出现这个错误提示意味着在运行 make menuconfig 命令时&#xff0c;系统找不到 ncurses 库。ncurses 是一种文本用…

iPhone手机记笔记工具选择用哪个

iPhone手机大家应该都比较熟悉&#xff0c;其使用性能是比较流畅的&#xff0c;在iPhone手机上记录笔记可以帮助大家快速地进行总结工作、记录工作内容等&#xff0c;在iPhone手机上记笔记工具选择用哪个呢&#xff1f; 可以在iPhone手机上使用的笔记工具是比较多的&#xff0…

Vue3中使用tinymce全功能演示,包括开源功能

效果图&#xff1a; 1、下载插件: npm i tinymce npm i tinymce/tinymce-vue 2、在node_modules文件夹中找到tinymce下的skins复制到项目public文件夹中 &#xff08;可以先创建一个tinymce文件夹&#xff09;&#xff1a; 3、在tinymce官网中下载中文包&#xff0c;并放在刚…