设计模式——适配器模式

引入实例

说起适配器其实在我们的生活中是非常常见的,比如:学校的宿舍的电压都比较低,而有的学生想使用大功率电器,宿舍的就会跳闸,然而如果你使用一个适配器(变压器)就可以使用了(温馨提示宿舍使用大功率电器不太安全,容易引起火灾,希望大家谨慎使用)。

又比如说,有的插座都是三孔的,而我们用的大部分电器是两孔的,这时我们可以使用一个适配器,适配器本身是三孔的,它可以直接插到三孔的插头上,适配器本身可以提供一个两孔的插座,然后我们就可以插到适配器上了,这样我们原本只能插到两孔上的插头就能用三孔的插座了。

适配器模式的相关概念

适配器模式的正式定义

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

适配器模式分为

  • 类适配器模式
  • 对象适配器模式

适配器模式的结构

适配器模式里面总共拥有三个角色,它们分别是:

  • 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
  • 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
  • 适配器(Adapter)类:它是一个转换器,通过继承(类适配器模式)或引用适配者的对象(对象适配器模式),把适配者接口转换成目标接口(也就是使用转换器将三头的插座转换成适合我们使用的两头插座),让客户按目标接口的格式访问适配者。

注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。

类适配器

类适配器的原理就是通过继承来实现适配器功能。

让Adapter实现Target接口,并且继承Adaptee,这样Adapter就具备Target和Adaptee的特性,就可以将两者进行转化。

举例:以不同设备使用不同交流电为例,通过电源适配器进行转换说明。

创建目标角色(Target)

public interface Target {int out();
}

创建源角色(Adaptee)

public class Adaptee{public int input() {System.out.println("输入交流电: 220V");return 220;}
}

创建适配器(Adapter)

public class Adapter extends Adaptee implements Target {@Overridepublic int out() {int input220V = super.input();int output = input220V / 2;System.out.println("输出交流电: " + output + "V");return output;}
}

客户端调用

public static void main(String[] args) {Target adapter = new Adapter();int result = adapter.out();System.out.println(result);
}

输入交流电: 220V
输出交流电: 110V
110

对象适配器

对象适配器的原理就是通过组合来实现适配器功能。

让Adapter实现Target接口,然后内部持有Adaptee实例,然后再Target接口规定的方法内转换Adaptee。

创建目标角色(Target)

public interface Target {int out();
}

创建源角色(Adaptee)

public class Adaptee{public int input() {System.out.println("输入交流电: 220V");return 220;}
}

创建适配器(Adapter)

public class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic int out() {int output = adaptee.input() / 2;System.out.println("输出交流电: " + output + "V");return output;}
}

客户端调用

    public static void main(String[] args) {Target adapter = new Adapter(new Adaptee());int result = adapter.out();System.out.println(result);}

输入交流电: 220V
输出交流电: 110V
110

接口适配器

接口适配器的使用场景是解决接口方法过多,如果直接实现接口,那么类会多出许多空实现的方法,类显得很臃肿。此时,使用接口适配器就能让我们只实现我们需要的接口方法,目标更清晰。

接口适配器的主要原理就是原理利用抽象类实现接口,并且空实现接口众多方法。

创建目标角色(Target)

public interface Target {int out1();int out2();int out3();int out4();
}

创建源角色(Adaptee)

public class Adaptee{public int input() {System.out.println("输入交流电: 220V");return 220;}
}

创建适配器(Adapter)

public class Adapter implements Target {protected Adaptee adaptee;public Adapter(Adaptee adaptee){this.adaptee = adaptee;}@Overridepublic int out1() {int input220V = adaptee.input();int output = input220V / 1;System.out.println("输出交流电: " + output + "V");return output;}@Overridepublic int out2() {int input220V = adaptee.input();int output = input220V / 2;System.out.println("输出交流电: " + output + "V");return output;}@Overridepublic int out3() {return 0;}@Overridepublic int out4() {return 0;}
}

客户端调用

    public static void main(String[] args) {Target adapter = new Adapter(new Adaptee());adapter.out1();System.out.println("---------------------");adapter.out2();System.out.println("---------------------");Target adapter2 = new Adapter(new Adaptee()) {@Overridepublic int out3() {int input220V = adaptee.input();int output = input220V / 3;System.out.println("输出交流电: " + output + "V");return output;}};adapter2.out3();System.out.println("---------------------");Target adapter3 = new Adapter(new Adaptee()) {@Overridepublic int out4() {int input220V = adaptee.input();int output = input220V / 4;System.out.println("输出交流电: " + output + "V");return output;}};adapter3.out4();}

输入交流电: 220V
输出交流电: 220V
---------------------
输入交流电: 220V
输出交流电: 110V
---------------------
输入交流电: 220V
输出交流电: 73V
---------------------
输入交流电: 220V
输出交流电: 55V

优缺点

适配器模式优点:

  • 可以让任何两个没有关联的类一起运行。
  • 提高了类的复用。
  • 增加了类的透明度。
  • 灵活性好。

适配器模式缺点:

  • 过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
  • 由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。

优点 :

  • 类适配器模式优点:由于适配器类是适配者类的子类,因此可以在适配器类中置换一些适配者的方法,使得适配器的灵活性更强。
  • 对象适配器模式优点:一个对象适配器可以把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。

缺点:

  • 类适配器模式缺点:对于Java、C#等不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为抽象类,不能为具体类,其使用有一定的局限性,不能将一个适配者类和它的子类都适配到目标接口。
  • 对象适配器模式缺点:与类适配器模式相比,要想置换适配者类的方法就不容易。如果一定要置换掉适配者类的一个或多个方法,就只好先做一个适配者类的子类,将适配者类的方法置换掉,然后再把适配者类的子类当做真正的适配者进行适配,实现过程较为复杂。

类适配器和对象适配器的区别:

  • 前者类之间的耦合度比后者高(这是因为类适配器模式使用的是继承的方式,而对象适配器模式使用的是聚合或者组合的方式)。
  • 类适配器模式要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些,用的更多的还是对象适配器模式。

应用场景

  1. 当一个系统需要使用另一个系统的接口时,但是两个系统的接口不兼容,可以使用适配器模式进行接口转换。
  2. 在数据处理方面,适配器模式可以用于将不同格式的数据适配到一个标准的数据格式上。
  3. 当我们需要复用一些已有的类的时候,这些类的接口与我们需要的接口不兼容,可以使用适配器将这些类的接口转换成我们需要的接口,从而实现类的复用。
  4. 适配器模式可以用于封装有缺陷的接口设计,使得客户可以通过适配器来使用这些缺陷的接口,而无需直接与其交互。
  5. 替换依赖的外部系统,使得系统可以在不修改源代码的情况下适应新的外部系统。

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

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

相关文章

深入理解linux内核--块设备驱动程序

块设备的处理 块设备驱动程序上的每个操作都涉及很多内核组件;其中最重要的一些如图14-1所示。 例如,我们假设一个进程在某个磁盘文件上发出一个read()系统调用 ——我们将会看到处理write请求本质上采用同样的方式。 下面是内核对进程请求给予回应的一…

煤矿调度IP语音对讲广播模块一键求助对讲矿用调度通信系统SIP语音对讲求助终端

硬件接口描述 SV-2101VP/ SV-2103VP系列网络音频模块,所有外部连接采用端子,电源采用2.0mm的端子,网络采用标准RJ45连接器,其他都是1.25mm的连接器。 端口类型定义 P ———— 电源 AI ———— 模拟输入(在这里是音…

微信小程序前后端开发快速入门(完结篇)

这篇是微信小程序前后端快速入门完结篇了,今天利用之前学习过的所有知识做一个新的项目「群登记助手v1.0」小程序。 整体技术架构:小程序原生前端小程序云开发。 经历了前面教程的学习,大家有了一定的基础,所以本次分享重心主要是…

Ubuntu服务器service版本初始化

下载 下载路径 官网:https://cn.ubuntu.com/ 下载路径:https://cn.ubuntu.com/download 服务器:https://cn.ubuntu.com/download/server/step1 点击下载(22.04.3):https://cn.ubuntu.com/download/server…

【jwt】JWT原理,JWT是用来解决什么问题的,如何自定义生成JWT数据,并且实现jwt数据的解码

JWT: JSON Web Token 1. jwt概述 用户登录成功后,服务端 如何知道客户端的每次请求对应的是哪个用户呢?怎么做:目前有两种方式实现. 1.1. 一是通过sessionId的方式,登录成功后服务端返回sessionId给客户端&#xff0…

【数据结构】栈与队列

1 栈 1.1 栈的概念及结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出 LIFO (Last In First Out) 的原则。 压栈:栈…

JupyterHub实战应用

一、JupyerHub jupyter notebook 是一个非常有用的工具,我们可以在浏览器中任意编辑调试我们的python代码,并且支持markdown 语法,可以说是科研利器。但是这种情况适合个人使用,也就是jupyter notebook以我们自己的主机作为服务器…

uni-app中监听网络状态,并在嵌入webView页面的组件中添加网络监测

uni-app中监听网络状态,并在嵌入webView页面的组件中添加网络监测 uni-app中监听网络状态 下载插件 打开网络异常组件页面,点击"下载插件并导入HBuilderX"按钮,打开HBuilderX软件后,选择需要导入插件的项目&#xff…

机器学习与模型识别1:SVM(支持向量机)

一、简介 SVM是一种二类分类模型,在特征空间中寻找间隔最大的分离超平面,使得数据得到高效的二分类。 二、SVM损失函数 SVM 的三种损失函数衡量模型的性能。 1. 0-1 损失: 当正例样本落在 y0 下方则损失为 0,否则损失为…

系统架构设计师-信息安全技术(1)

目录 一、信息安全基础 1、信息安全五要素 2、网络安全漏洞 3、网络安全威胁 4、安全措施的目标 二、信息加解密技术 1、对称加密 2、非对称加密 3、加密算法对比 三、密钥管理技术 1、数字证书 2、PKI公钥体系 四、访问控制技术 1、访问控制基本模型 2、访问控制的实现技术…

【Linux命令详解 | ssh命令】 ssh命令用于远程登录到其他计算机,实现安全的远程管理

文章标题 简介一,参数列表二,使用介绍1. 连接远程服务器2. 使用SSH密钥登录2.1 生成密钥对2.2 将公钥复制到远程服务器 3. 端口转发3.1 本地端口转发3.2 远程端口转发 4. X11转发5. 文件传输与远程命令执行5.1 文件传输5.1.1 从本地向远程传输文件5.1.2 …

深度学习入门-3-计算机视觉-图像分类

1.概述 图像分类是根据图像的语义信息对不同类别图像进行区分,是计算机视觉的核心,是物体检测、图像分割、物体跟踪、行为分析、人脸识别等其他高层次视觉任务的基础。图像分类在许多领域都有着广泛的应用,如:安防领域的人脸识别…

软考笔记——9.软件工程

软件工程的基本原理:用分阶段的生命周期计划严格管理、坚持进行阶段评审、实现严格的产品控制、采用现代程序设计技术、结果应能清除的审查、开发小组的人员应少而精、承认不断改进软件工程事件的必要性。 软件工程的基本要素:方法、工具、过程 软件生…

babylonjs基于自定义网格生成围栏动画

效果: import { Vector3, Mesh, MeshBuilder, StandardMaterial, Texture, Animation, Color3 } from "babylonjs/core"; import imgUrl from "./image/headerwangge2.png" // 创建模型护栏特效 export default class CreateRail {constructor…

小程序swiper一个轮播显示一个半内容且实现无缝滚动

效果图&#xff1a; wxml&#xff08;无缝滚动&#xff1a;circular"true"&#xff09;&#xff1a; <!--components/tool_version/tool_version.wxml--> <view class"tool-version"><swiper class"tool-version-swiper" circul…

数模论文写作细节要求

目录 优秀论文必要条件 数学建模的基本思路 第一步&#xff1a;了解问题——查文献、找数据 第二步&#xff1a;阐述要解决什么问题、用什么方法 其余步骤&#xff1a;给出数学模型、计算求解、对比结果与真实情况、应用于现实问题。 使用某种数学方法的理由和依据 创…

Python爬虫性能优化:多进程协程提速实践指南

各位大佬们我又回来了&#xff0c;今天我们来聊聊如何通过多进程和协程来优化Python爬虫的性能&#xff0c;让我们的爬虫程序6到飞起&#xff01;我将会提供一些实用的解决方案&#xff0c;让你的爬虫速度提升到新的高度&#xff01; 1、多进程提速 首先&#xff0c;让我们来看…

cs231n assignment2 q5 PyTorch on CIFAR-10

文章目录 嫌啰嗦直接看源码Q5 :PyTorch on CIFAR-10three_layer_convnet题面解析代码输出 Training a ConvNet题面解析代码输出 ThreeLayerConvNet题面解析代码输出 Train a Three-Layer ConvNet题面解析代码输出 Sequential API: Three-Layer ConvNet题面解析代码输出 CIFAR-1…

BT利器之wazuh

目录 一、什么是wazuh 二、wazuh的安装 1.仓库安装 2.虚拟机OVA安装 3.其他安装方式 三、浅析wazuh的规则、解码器等告警原理以及主动响应 1.主动响应(active-response) 2.告警信息(alerts) 3.规则以及解码器(rules and decoders) 3.1.规则 3.2.解码器 4.linux后门r…

【Matter】基于Ubuntu 22.04搭建matter开发环境:chip-tool 配网之 matter-over-wifi

前言 主要是记录一下学习过程&#xff0c;梳理下思路&#xff0c;抛转~ 官方的开发环境&#xff0c;基于Linux版本&#xff0c;官方的环境是基于树莓派环境的&#xff0c;原理其实也比较明了&#xff0c;目的也比较明确&#xff0c;就是达到Linux 主机和wifi 路由在同一局域网…