当前位置: 首页 > news >正文

适配器模式-java实现

意图

复用已经存在的接口,与所需接口不一致的类。即将一个类(通常是旧系统中的功能类),通过适配器转化成另一个接口的实现。(简单来说,就是复用旧系统的功能,去实现新的接口)

我们举一个框架中使用的例子:springMVC中的dispatchServlet中,执行流程是先获取请求对应的映射方法全类名,然后找到该方法对应的适配器,这就是适配器模式的使用,因为springMVC需要执行方法后,返回一个ModelAndView对象。但是我们直接反射执行方法,是返回不了这个对象的,这就需要适配器模式上场帮我们去适配返回一个ModelAndView了。

我们举个生活中的例子:

适配器模式将一个类的程序设计接口转换成另一个接口术这很像变压器把一种电压变换成另一种电压。例如,美国的生活用电电压是110 V,而中国的电压是220 V。如果要在中国使用美国电器,就必须有一个能把220 V电压转换成110 V电压的变压器,这个变压器就是一个Adapter。

从下面两个图片我们可以知道适配器模式的本意:我们可以这样理解,220V插座提供的功能是220v供电的功能,任何电器只需要供电就能正常运作。美国电器同样需要供电,但是供电的类型有点特殊,需要110v的供电,但是我们项目中只有220v的接口,那么就需要一个转换,这个转换器就是我们后来所说的适配器,即Adapter。

那么美国电器,就是新的功能规范,需要的功能类型和旧接口是一致的,只是不能直接使用旧接口,所以需要适配器去对旧接口进行转换操作

原本中国的电器使用

 

使用变压器后的美国电器使用

 

类图描述

类的适配器模式结构

通过继承来实现可用的类结构

可以看出,Adaptee类没有Request方法(其实不算没有,Adaptee中的不能直接适配Request的功能),而客户期待这个方法。为了使客户能够使用Adaptee类,需要提供一个中间环节,即Adapter类,Adapter类实现了Target接口,并继承自Adaptee,Adapter类的Request方法重新封装了Adaptee的SpecificRequest方法,实现了适配的目的。因为Adapter与Adaptee是继承的关系,所以这决定了这个适配器模式是类的。

 

适配器模式涉及以下角色:

(1)目标(Target)角色: 是客户所期待的接口。因为java不支持多继承,所以Target必须是接口,不可以是类。

(2)源(Adaptee): 需要适配的类,也就是旧系统中已经有的类。

(3)适配器(Adapter)角色: 把源接口转换成目标接口,这一角色必须是类。

 

 

 请注意:适配器模式的要点是,新的目标接口所需要的功能跟旧接口的一致,但是又有一些差别,因此需要适配器Adapter来进行转换处理,而不是添加新的接口等,切勿跟装饰模式搞混了。

对象的适配器结构

跟类的适配器结构区别在于,Adapter中保持了一个旧的对象的引用,而不是通过继承来实现

 

例子:

假设目前有一个日期的工具类对象PersonDate,返回的内容是当前的时间戳,而此时,用户希望得到(年-月-日),也就是年月日这样类型的,于是这个新的规范,抽象为一个接口UserDate

首先创建PersonDate类

public class PersonDate {//返回当前日期的时间戳public Long getNowDate(){Date date=new Date();return date.getTime();}
}

然后创建新接口UserDate

public interface UserDate {//返回当前日期的格式化内容  年-月-日String getNowDateString();
}

创建适配器AdapterDate,这里采用对象适配器的方式,在适配器中保留旧对象的引用

public class AdapterDate implements UserDate{//保持旧实例的引用private PersonDate personDate;public AdapterDate(PersonDate personDate) {this.personDate = personDate;}//具体的转换方法@Overridepublic String getNowDateString() {//获取时间戳Long nowDate = personDate.getNowDate();//转化成date对象Date date=new Date(nowDate);SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");String dateString = format.format(date);return dateString;}
}

客户端测试:

public class Client {public static void main(String[] args) {//客户端使用旧的接口PersonDate personDate=new PersonDate();System.out.println(personDate.getNowDate());//使用适配器对象UserDate userDate=new AdapterDate(personDate);System.out.println(userDate.getNowDateString());}
}

运行结果:

 

 

小结:

到这里,我们可以知道适配器模式的理念,就是复用旧系统中的功能类,去适配新的接口,而新的接口,恰好需要和旧系统中对象相同的功能(不完全相同,但是大体一致),这时候就需要适配器去将旧功能对象去转化成为新接口的实现

相关文章:

适配器模式-java实现

意图 复用已经存在的接口,与所需接口不一致的类。即将一个类(通常是旧系统中的功能类),通过适配器转化成另一个接口的实现。(简单来说,就是复用旧系统的功能,去实现新的接口) 我们举…...

【elasticSearch系】3.完整搭建详尽版elk

话不多说,我们先看下经典的elk 是由哪些组件搭建组合起来的 elasticsearch和kibana搭建 可以查看之前我们搭建elasticsearch和kibana 的这篇文章 logstash搭建 为了和之前我们搭建elasticsearch和kibana版本保持一致,这里我们还是选择7.17.3 下载地址 点击下载,这里为了…...

代码随想录day04

24. 两两交换链表中的节点 ● 力扣题目链接 ● 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 ● 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 思路 ● 使用迭代的方法,分析交换逻辑即可 ○ …...

[Realtek] WPA_SUPPLICANT + WPA_CLI使用指南

开启wpa_supplicant wpa_supplicant –Dnl80211 -iwlan0 -c ./wpa.conf –B 或者 wpa_supplicant -Dwext -iwlan0 -c ./wpa.conf -B 扫描AP wpa_cli -p/var/run/wpa_supplicant scan 查看AP扫描结果 wpa_cli -p/var/run/wpa_supplicant scan_results 连接到热点 OPEN…...

# ⛳ Docker 安装、配置和详细使用教程-Win10专业版

目录 ⛳ Docker 安装、配置和详细使用教程-Win10专业版🚜 一、win10 系统配置🎨 二、Docker下载和安装🏭 三、Docker配置🎉 四、Docker入门使用 ⛳ Docker 安装、配置和详细使用教程-Win10专业版 🚜 一、win10 系统配…...

Linux 教程

目录 Linux 教程 内核引导 运行init 运行级别 系统初始化 Linux 系统目录结构 Linux 教程 Lin...

图论——最短路算法

引入&#xff1a; 如上图&#xff0c;已知图G。 问节点1到节点3的最短距离。 可心算而出为d[1,2]d[2,3]112,比d[1,3]要小。 求最短路径算法&#xff1a; 1.Floyd(弗洛伊德) 是一种基于三角形不等式的多源最短路径算法。边权可以为负数 表现为a[i,j]a[j,k]<a[i,k]。 …...

在项目中增加网络加载需要考虑什么?

1、下载器 网络加载的第一步肯定是下载&#xff0c;那么选择一个合适的下载器是十分重要的&#xff0c;这个下载器最好支持什么功能&#xff1f; 多线程下载&#xff08;同时需要服务端支持&#xff0c;下载时可指定range&#xff09; 断点续传 通用性&#xff08;其他位置也…...

阿里云服务器部署RabbitMQ流程

阿里云百科分享使用阿里云服务器部署RabbitMQ流程&#xff0c;RabbitMQ是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理软件&#xff0c;用于在分布式系统中存储转发消息&#xff0c;有良好的易用性、扩展性和高可用性。本文介绍如何通过ECS实例部署Rabbi…...

青大数据结构【2014】

一、单选 二、简答 为了解决顺序队列的假溢出问题&#xff0c;提出了循环队列&#xff0c;即把存储队列的表从逻辑上看成一个环 判别队列空和满有三种方法&#xff1a; 1&#xff09;采用计数器判别&#xff0c;空时&#xff0c;计数器为0&#xff1b;满时&#xff0c;计数器…...

Ansible Playbook快速部署一主多从MySQL集群

部署目标&#xff1a; 1、快速部署一套一主两从的mysql集群 2、部署过程中支持交互式定义安装目录及监听端口号 部署清单目录结构&#xff1a; rootmaster:/opt/mysql# tree . . ├── group_vars │ └── all.yml ├── hosts ├── mysql.yml └── roles└── mys…...

27.Netty源码之FastThreadLocal

highlight: arduino-light FastThreadLocal FastThreadLocal 的实现与 ThreadLocal 非常类似&#xff0c;Netty 为 FastThreadLocal 量身打造了 FastThreadLocalThread 和 InternalThreadLocalMap 两个重要的类。下面我们看下这两个类是如何实现的。 FastThreadLocalThread 是对…...

linux下离线安装docker

linux下离线安装docker 一、安装docker Docker 官网离线安装文档 https://docs.docker.com/engine/install/binaries/ 整理步骤如下&#xff1a; 官网下载 docker 安装包&#xff0c;地址为 https://download.docker.com/linux/static/stable/&#xff0c;如果是x86就选择x…...

SQL server 异地备份数据库

异地备份数据库 1.备份服务器中设置共享文件夹 2.源服务器数据库中添加异地备份代理作业 EXEC sp_configure show advanced options, 1;RECONFIGURE; EXEC sp_configure xp_cmdshell, 1;RECONFIGURE; declare machine nvarchar(50) 192.168.11.10 --服务器IP declare pa…...

高并发系统设计要点

在系统设计时&#xff0c;如果能预先看到一些问题&#xff0c;并在设计层面提前解决&#xff0c;就会给后期的开发带来很大的便捷。相反&#xff0c;有缺陷的架构设计可能会导致后期的开发工作十分艰难&#xff0c;甚至会造成“推倒重来”的情形。因此&#xff0c;在系统设计阶…...

Redis 拒绝服务漏洞(CVE-2023-28856)修复处理

一、漏洞描述 Redis Labs Redis是美国Redis Labs公司的一套开源的使用ANSI C编写、支持网络、可基于内存亦可持久化的日志型、键值&#xff08;Key-Value&#xff09;存储数据库&#xff0c;并提供多种语言的API。 Redis 7.0.0 到 7.0.10版本、6.2.0 到 6.2.11版本、6.0.0 到 …...

Android保存网页的方法

首先要使用js交互就需要懂原理&#xff1a; 感谢大佬&#xff1a;js中document节点获取页面元素的六种方式 1.querySelector()方法 描述&#xff1a;本方法用于根据给定的选择器选中页面元素 如果有多个元素满足条件&#xff0c;则返回第一个满足条件的元素节点 语法&#xff…...

P2P 网络,PING程序。

没有废话,直接上版本号和代码,以及讲解。 crate版本号libp2p0.52.1tokio1.30.0依赖配置: [dependencies] tokio = { version="1.30.0", features=["full"] } libp2p = { version="0.52.1", features=["tokio","dns", &q…...

OPENCV C++(十二)模板匹配

正常模板匹配函数 matchTemplate(img, templatee, resultMat, 0);//模板匹配 这里0代表的是方法&#xff0c;一般默认为0就ok img是输入图像 templatee是模板 resultmat是输出 1、cv::TM_SQDIFF&#xff1a;该方法使用平方差进行匹配&#xff0c;因此最佳的匹配结果在结果为…...

【配置环境】Linux下安装MySQL

目录 一&#xff0c;环境 二&#xff0c;安装步骤 1.使用包管理器安装MySQL 2.配置MySQL的安全选项 3.设置root用户使用密码进行身份验证&#xff08;可选&#xff09; 三&#xff0c;拓展知识 1.如何修改MySQL的密码策略&#xff1f; 一&#xff0c;环境 VMware Workst…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...