适配器模式-不兼容结构的协调

 去英语国家旅游时,我们只会说中文,为了与当地人交流,我们需要购买个翻译器,将中文翻译成英文,而这运用了适配器模式。

1 概述

适配器模式(Adapter Pattern),将一个接口转换成客户喜欢的另一个接口,使接口不兼容的那些类可以一起工作。这里的接口指广义的接口,它可以表示一个方法或者一组方法的集合。适配器又称为包装器。

图 对象适配器模式

Target: 目标抽象类,定义客户所需接口。

Adapter:适配器类,可以调用另一个接口,作为一个适配器,对Adaptee和Target进行匹配。

Adaptee: 被适配者类,定义了一个已经存在的接口,这个接口需要适配。被适配者类一般是一个具体的类。

public class ChineseAdaptee {public void speakChinese(String content) {System.out.println(content);}}public interface EnglishTarget {void speakEnglish(String content);}public class EnglishToChineseAdapter implements EnglishTarget{private final ChineseAdaptee chineseAdaptee;public EnglishToChineseAdapter(ChineseAdaptee chineseAdaptee) {this.chineseAdaptee = chineseAdaptee;}@Overridepublic void speakEnglish(String content) {if ("hello".equals(content)) {chineseAdaptee.speakChinese("你好");} else {chineseAdaptee.speakChinese("对不起,听不懂。");}}
}public class Client {public static void main(String[] args) {ChineseAdaptee chineseAdaptee = new ChineseAdaptee();EnglishTarget englishTarget = new EnglishToChineseAdapter(chineseAdaptee);englishTarget.speakEnglish("hello");englishTarget.speakEnglish("nice to meet you");
//        运行结果:
//        你好
//        对不起,听不懂。}}

1.1 类适配器模式

类适配器和对象适配器最大的区别在于其匹配器和适配者之间的关系是继承关系。

图 类适配器模式

由于Java语言不支持多重类继承,因此类适配器模式的使用受到了很多限制。

需求:老代码中有一个加密算法,把二进制数据使用md5算法加密,生成一个字符串。新需求中,要求对用户输入的“用户名+密码”字符串进行md5加密。

图 加密需求设计方案

public class Md5Adaptee {public String md5Encrypt(String str) {return "md5加密" + str;}}public interface UserInfoEncryptTarget {String encrypt(String username,String password);}public class UserInfoEncryptAdapter extends Md5Adaptee implements UserInfoEncryptTarget{@Overridepublic String encrypt(String username, String password) {return md5Encrypt(username + password);}
}public class Client {public static void main(String[] args) {UserInfoEncryptTarget userInfoEncryptTarget = new UserInfoEncryptAdapter();System.out.println(userInfoEncryptTarget.encrypt("admin","123456"));}}

​​​​​​​1.2 缺省适配器模式(接口适配器)

当不需要实现一个接口所提供的方法时,可以先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现,那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求。

它适用于不想使用一个接口中的所有方法的情况。

图 接口适配器

ServiceInterface: 适配者接口,通常在该接口声名了大量的方法。

AbstractService: 缺省适配器类,使用空方法形式实现了在ServiceInterface接口中声名的方法。通常将它定义为抽象类,因为对它进行实例化没有任何意义。

ConcreteService: 具体业务类,继承了缺省适配器类,可以根据需要有选择性地覆盖在适配器类中定义的方法。

需求:有个文件流接口,定义了读文件、写文件及文件安全性验证三个方法。现在想定义一个类,用来验证文件安全性,而不想实现其他方法。

public interface FileInterface {void writeFile(String path, OutputStream outputStream);void readFile(String path);void verifyFile(String path);}public abstract class FileAbstract implements FileInterface{@Overridepublic void writeFile(String path, OutputStream outputStream) {throw new RuntimeException("不能操作这个方法");}@Overridepublic void readFile(String path) {throw new RuntimeException("不能操作这个方法");}@Overridepublic void verifyFile(String path) {throw new RuntimeException("不能操作这个方法");}}public class VerifyFile extends FileAbstract{@Overridepublic void verifyFile(String path) {System.out.println("安全性验证:" + path);}}public class Client {public static void main(String[] args) {FileInterface fileInterface = new VerifyFile();fileInterface.verifyFile("hello.java");}}

适配器名称

实现

作用及优势

对象适配器

在适配类中关联一个被适配者对象,通过调用被适配者对象的方法来实现适配。

适配目标接口。扩展方便,可动态替换被适配者,来适配其他类。

类适配器

适配类继承被适配者类。

适配目标接口。使用继承方式,不方便扩展,但是实现方法比较方便。

接口适配器

通过一个抽象类来实现接口中的所有方法,具体类继承抽象类,根据需求重写特定的方法。

不想实现一个接口中的所有方法。

表 三种类型适配器模式对比

2 优缺点

优点:

  1. 将目标类和适配者类解耦,通过引入一个适配器来重用现有适配者类的功能,无须修改原有接口。
  2. 灵活性和扩展性很好,可以动态替换被替换者及适配器,符合开闭原则。
  3. 对于不想实现接口中所有方法的场景,适配器模式能按需求重写需要实现的方法。

缺点:

  1. Java不支持多重类继承,类适配器一次最多只能适配一个适配器。且目标抽象类只能为接口。有一定局限性。

3 适用场景

  1. 想适配老代码的相关接口。
  2. 不想实现接口中的所有方法。

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

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

相关文章

idea-控制台输出乱码问题

idea-控制台输出乱码问题 现象描述: 今天在进行IDEA开发WEB工程调式的时候控制台日志输出了乱码,如下截图 其实开发者大多都知道乱码是 编码不一致导致的,但是有时候就是不知到哪些地方不一致,今天我碰到的情况可能和你的不相同…

APACHE KAFKA本机Hello World教程

目标 最近想要简单了解一下Apache Kafka,故需要在本机简单打个Kafka弄一弄Hello World级别的步骤。 高手Kafka大佬们,请忽略这里的内容。 步骤 Apacha Kafka要求按照Javak8以上版本的环境。从官网下载kafka并解压。 启动 # 生产kafka集群随机ID KA…

未来Mac下载站怎么打不开了

重要公告: 未来软件园因业务需要现更换域名 原域名:Mac.orsoon.com 更为新域名:未来mac下载-Mac软件-mac软件下载-mac软件大全 程序已全面转移,请访问新域名

软件基础问答题

性能: 负载压力测试是指在一定约束条件下测试系统所能承受的并发用户量、运行时间、数据量等,以确定系统所能承受的最大负载压力。 负载测试是通过逐步增加系统负载,测试系统性能的变化,并最终确定在满足性能指标的情况下&#xf…

【技能实训】DMS数据挖掘项目-Day11

文章目录 任务12【任务12.1】创建用户信息表【任务12.2】在com.qst.dms.entity下创建用户实体类User,以便封装用户数据【任务12.3】在com.qst.dms.service下创建用户业务类UserService【任务12.4】在项目根目录下创建图片文件夹images,存储dms.png【任务…

计算机毕业论文选题推荐|软件工程|信息管理|数据分析|系列一

文章目录 导文题目导文 计算机毕业论文选题推荐|软件工程|信息管理 (***语言)==使用其他任何编程语言 例如:基于(***语言)门窗账务管理系统的设计与实现 得到:基于JAVA门窗账务管理系统的设计与实现 基于vue门窗账务管理系统的设计与实现 等等 题目 基于requests多线程…

微信小程序——字符串截取

indexOf() : 判断一个字符是否在字符串 中 存在,如果存在返回该元素或字符第一次出现 的 位置 的 索引,不存在返回-1。 lastIndexOf() : 返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。…

静态数码管显示

学习芯片: EP4CE6F17C8 本次学习使用的为共阴极数码管,即用低电平点亮数码管,同样可知,共阳极数码管的阳极连在一起,即用高电平点亮数码管。 八段数码管示意图: a,b,c,d,e,f,g,dg表示八段数码管时&#…

7、sentinel使用和源码分析

一、分布式系统遇到的问题 1、服务雪崩效应 在分布式系统中,由于网络原因或自身的原因,服务一般无法保证 100% 可用。如果一个服务出现了问题,调用这个服务就会出现线程阻塞的情况,此时若有大量的请求涌入,就会出现多条线程阻塞等待&#x…

力扣 135. 分发糖果

题目来源:https://leetcode.cn/problems/candy/description/ C题解(来源代码随想录): 先从左往右比较,右边孩子评分比左边高就多发1颗糖,否则就只发1颗;再从右往左比较,左边孩子评分…

机械臂的雅克比矩阵推导

1. 线速度和角速度的递推通式推导 p i p i − 1 R i − 1 r i − 1 , i i − 1 \mathbf{p}_{i}\mathbf{p}_{i-1}\mathbf{R}_{i-1} \mathbf{r}_{i-1, i}^{i-1} pi​pi−1​Ri−1​ri−1,ii−1​ p i − 1 \mathbf{p}_{i-1} pi−1​是 { i − 1 } \{i-1\} {i−1}坐标系的原点的…

记一次ruoyi中使用Quartz实现定时任务

一、首先了解一下Quartz Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标…

UE4/5AI制作基础AI跳跃(适合新手)

目录 制作 添加逻辑 添加导航链接代理 结果 在上一章中,我们讲解了简单的AI跟随玩家,制作了一个基础的ai。 UE4/5AI制作基础AI(适合新手入门,运用黑板,行为树,ai控制器,角色类,任…

4、深入理解ribbon

一、负载均衡的两种方式 服务器端负载均衡 传统的方式前端发送请求会到我们的的nginx上去,nginx作为反向代理,然后路由给后端的服务器,由于负载均衡算法是nginx提供的,而nginx是部署到服务器端的,所以这种方式又被称为…

linux之Ubuntu系列(-)常见指令 重定向

Ubuntu 中文 版本 注意点 通过修改语言改成英文 在终端录入:export LANGen_US 在终端录入:xdg-user-dirs-gtk-update 单用户和多用户 命令格式 command [-选项] [参数] –查看命令的帮助 命令 --help man 命令 |操作键| 功能| |空格键|-显示手册的下…

OSS对象存储后端实现+Vue实现图片上传【基于若依管理系统开发】

文章目录 基本介绍术语介绍图片上传方式介绍普通上传用户直传应用服务器签名后直传 OSS对象存储后端实现maven配置文件配置类ServiceController 图片上传前端图片上传组件api页面使用组件组件效果 基本介绍 术语介绍 Bucket(存储空间):用于…

【论文】基于GANs的图像文字擦除 ——2010.EraseNet: End-to-End Text Removal in the Wild(已开源)

pytorch官方代码:https://github.com/lcy0604/EraseNet 论文:2010.EraseNet: End-to-End Text Removal in the Wild 网盘提取码:0719 一、图片文字去除效果 图10 SCUT-EnsText 真实数据集的去除 第一列原图带文字、第二列为去除后的标签&a…

爆肝整理,Postman接口测试-全局变量/接口关联/加密/解密(超细)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 全局变量和环境变…

AJAX:宏任务与微任务

异步任务划分为了 宏任务:由浏览器环境执行的异步代码 微任务:由 JS 引擎环境执行的异步代码 宏任务和微任务具体划分: 左边表格是宏任务,右边是微任务 事件循环模型 /*** 目标:阅读并回答打印的执行顺序 */ console…

Spark编程-键值对RDD(K,V)创建及常用操作

简述 SparkRDD中可以包含任何类型的对象,在实际应用中,“键值对”是一种比较常见的RDD元素类型,分组和聚合操作中经常会用到,尤其是groupByKey和reduceByKey。 Spark操作中经常会用到“键值对RDD”(Pair RDD&a…