设计模式之适配器模式(Adapter)

一、适配器模式介绍

        适配器模式(adapter pattern )的原始定义是:将类的接口转换为客户期望的另一个接口,

        适配器可以让不兼容的两个类一起协同工作。 

        适配器模式是用来做适配,它将不兼容的接口转换为可兼容的接口,让原本由于接口

        不兼容而不能一起工作的类可以一起工作。适配器模式有两种实现方式:类适配器和

        对象适配器。其中,类适配器使用继承关系来实现,对象适配器使用组合关系来实现。

        类适配器模式的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部

        结构,所以应用相对较少些。

二、适配器模式原理

       适配器模式(Adapter)包含以下主要角色:

             1)目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。

             2)适配者(Adaptee)类:适配者即被适配的角色,它是被访问和适配的现存组件库

                  中的组件接口。

            3)适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配

                  者接口转换成目标接口,让客户按目标接口的格式访问适配者。

       类适配器类一般是继承 “适配者类(适配者的具体实现)” 并实现目标接口,而对象适配器

       器类一般是在适配器类中引用适配者类对象;适配器模式结构图如下:

       类适配器模式结构图:

              

       对象适配器模式结构图:

               

三、适配器模式应用示例

        以电脑目前只能读取SD卡的信息为例来看下适配器模式的使用
        一台电脑目前只能读取SD卡的信息,这时我们想要使用电脑读取TF卡的内容, 就需要将TF卡

        加上卡套,转换成SD卡,最后将TF卡中的内容读取出来

1、类适配器模式实现

      实现方式:

             类适配器类继承 “适配者类的具体实现(即TFCardImpl)” 并实现目标接口SDCard

      UML类图如下:

              

      具体代码实现如下:

/*** 类适配器* 以电脑目前只能读取SD卡的信息为例来看下适配器模式的使用* 一台电脑目前只能读取SD卡的信息,这时我们想要使用电脑读取TF卡的内容, 就需要将TF卡加上卡套,转换成SD卡** SD卡接口--目标(Target)接口*/
public interface SDCard {//读取SD卡方法String readSD();//写入SD卡功能void writeSD(String msg);
}/******************************************************** SD卡实现类*********************************************************/
public class SDCardImpl implements SDCard{@Overridepublic String readSD() {String msg = "sd card reading data";return msg;}@Overridepublic void writeSD(String msg) {System.out.println("sd card write data : " + msg);}
}/*** TF卡接口--适配者*/
public interface TFCard {//读取TF卡方法String readTF();//写入TF卡功能void writeTF(String msg);
}/******************************************************** TF卡实现类** *******************************************************/
public class TFCardImpl implements TFCard{@Overridepublic String readTF() {String msg = "tf card reading data";return msg;}@Overridepublic void writeTF(String msg) {System.out.println("tf card write data : " + 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);}
}******************************************************** 电脑类,* 电脑类只能读取sd卡********************************************************/
public class Computer {public String read(SDCard sdCard){return sdCard.readSD();}
}//测试
public class Test {public static void main(String[] args) {Computer computer = new Computer();SDCard sdCard = new SDCardImpl();System.out.println(computer.read(sdCard));System.out.println("========================");SDAdapterTF adapterTF = new SDAdapterTF();System.out.println(computer.read(adapterTF));}
}

2、对象适配器模式实现

      实现方式:

             对象适配器模式可釆用将现有组件库中已经实现的组件引入适配器类中,该类同时实

             现当前系统的业务接口。

      对象适配器模式UML类图如下:

              

      代码实现:

            在类适配器模式的代码基础上我们只需要修改 “适配器类” 就可以了,具体代码如下:

            

/******************************************************** 适配器类* 对象适配器类--通过组合的方式来实现适配********************************************************/
public class SDAdapterTF2 implements SDCard {private TFCard tfCard;public SDAdapterTF2(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);}
}

四、适配器模式总结

1、适配器模式优点

      1)将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无序修改原有结构

      2)增加了类的透明性和复用性,将具体业务实现过程封装在适配者类中,对于客户端类而言

            是透明的,而且提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用。

      3)灵活性和扩展性都非常好,通过使用配置文件可以很方便的更换适配器,也可以在不修改

            原有代码的基础上增加新的适配器类,符合开闭原则。

     

2、适配器模式缺点

2.1、类适配器的缺点

      1)对于Java等不支持多重继承的语言,一次最多只能适配一个适配者类,不能同时适配

            多个适配者

      2)适配者类不能为最终类,即不能被关键字final修饰

2.2、对象适配器的缺点

      1)与类适配器模式相比较,在该模式下要在适配器中置换适配者类的某些方法比较麻烦。

3、适配器模式适用场景

      1)统一多个类的接口设计时:

            某个功能的实现依赖多个外部系统(或者说类)。通过适配器模式,将它们的接口适配为

            统一的接口定义

      2)需要依赖外部系统时:

            当我们把项目中依赖的一个外部系统替换为另一个外部系统的时候,利用适配器模式,可

            以减少对代码的改动

      3)原有接口无法修改时或者原有接口功能太老旧但又需要兼容时:

            如JDK1.0 Enumeration 到 Iterator 的替换,适用适配器模式保留 Enumeration 类,并将

           其实现替换为直接调用 Itertor

      4)适配不同数据格式时:

            如Slf4j 日志框架,定义打印日志的统一接口,提供针对不同日志框架的适配器

4、代理、桥接、装饰与适配4种设计模式的区别

      代理、桥接、装饰器、适配器,这 4 种模式是比较常用的结构型设计模式。它们的代码结构

      非常相似。但其各自的用意却不同,简单说一下它们之间的关系:

      1)代理模式:

           代理模式在不改变原始类接口的条件下,为原始类定义一个代理类,主要目的是控制访问,

           而非加强功能,这是它跟装饰器模式最大的不同。

      2)桥接模式:

            桥接模式的目的是将接口部分和实现部分分离,从而让它们可以较为容易、也相对独立地

            加以改变。

      3)装饰器模式:

           装饰者模式在不改变原始类接口的情况下,对原始类功能进行增强,并且支持多个装饰器的

           嵌套使用。

      4)适配器模式:

           将一个类的接口转换为客户希望的另一个接口。适配器模式让那些不兼容的类可以一起工作

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

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

相关文章

2024年1月Java项目开发指南18:自定义异常输出

一般情况下,报错信息一大堆,值得注意的只有三个地方: 哪个文件发生了错误哪一行发生了错误错误原因是什么 只要知道这三个东西就能快速的定位到错误发生的位置并且根据提示解决。 如果你也喜欢我的这种异常输出(如文章顶部图) 那么可以参考以…

[M数学] lc3164. 优质数对的总数 II(因数分解+倍增+推公式+思维+好题)

文章目录 1. 题目来源2. 题目解析 1. 题目来源 链接:3164. 优质数对的总数 II 2. 题目解析 挺不错的一道 因数分解、倍增 的题目,需要一定的思维和推公式的能力才能解决。灵神的题解已经非常清晰易懂了,可以直接去看。 倍增思路&#xff…

大数据分析案例-基于逻辑回归算法构建抑郁非抑郁推文识别模型

🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 喜欢大数据分析项目的小伙伴,希望可以多多支持该系列的其他文章 大数据分析案例合集

(十八)、登陆 k8s 的 kubernetes-dashboard 更多可视化工具

文章目录 1、回顾 k8s 的安装2、确认 k8s 运行状态3、通过 token 登陆3.1、使用现有的用户登陆3.2、新加用户登陆 4、k8s 可视化工具 1、回顾 k8s 的安装 Mac 安装k8s 2、确认 k8s 运行状态 kubectl proxy kubectl cluster-info kubectl get pods -n kubernetes-dashboard3、…

如何启动一个OpenSearch

创建两个集群,标注 不含备用节点 选择集群版本和配置集群版本 冷热存储和专用主节点这个按需开启 然后是网络,是否使用自定义域名,集群开在VPC还是公网上。 选择是否开启认证: 访问策略,其实就是资源策略 维护时段…

Oracle 数据库安装和配置详解

Oracle 数据库安装和配置详解 Oracle 数据库是一款功能强大、广泛使用的企业级关系数据库管理系统 (RDBMS),适用于处理大型数据库和复杂事务。本文将介绍如何在 Linux 和 Windows 环境下安装 Oracle 数据库,并对其进行基本配置,帮助开发者快…

理解计算机系统_程序的机器级表示(特别篇):对比move和leaq看汇编语言中数据的传递,变量和指针的映射,指针的实现

前言 以<深入理解计算机系统>(以下称“本书”)内容为基础&#xff0c;对程序的整个过程进行梳理。本书内容对整个计算机系统做了系统性导引,每部分内容都是单独的一门课.学习深度根据自己需要来定 引入 汇编代码传递数据的机制令人费解.而这部分内容又是比较基础的,需要…

实例详解 | 借助 Langchain 和 Gemma 2 构建 RAG 应用

本文原作者&#xff1a;Connie Leung&#xff0c;谷歌开发者专家 (GDE)&#xff0c;原文发布于&#xff1a;DEV Community https://dev.to/railsstudent/build-a-rag-application-to-learn-angular-using-langchhtainjs-nestjs-htmx-and-gemma-2-5ggk 本文将为您介绍如何使用…

.Net基础1

.NET框架 项目结构 Connected Services是第三方服务MVC框架appsettings.json配置文件Program.cs控制台应用程序Properties里的json文件是配置启动方式 1. 基本开发 出现这个bug是因为防火墙没有把浏览器加入白名单&#xff0c;可以暂时先用http启动代替 第一步创建控制器&am…

数字化AI新赋能,智享AI直播:开启一个全新的直播时代!

数字化AI新赋能&#xff0c;智享AI直播&#xff1a;开启一个全新的直播时代! 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;技术正以前所未有的速度改变着我们的生活和工作方式。其中&#xff0c;AI直播技术的崛起&#xff0c;无疑是数字化时代的一大亮…

深入理解 C/C++ 指针

深入理解 C 指针&#xff1a;指针、解引用与指针变量的详细解析 前言 在 C 编程语言中&#xff0c;指针 是一个非常强大且重要的概念。对于初学者来说&#xff0c;指针往往会让人感到困惑不解。本文将通过形象的比喻&#xff0c;帮助大家深入理解指针、解引用与指针变量的概念…

ELK:Elasticsearch、Logstash、Kibana Spring Cloud Sleuth和Spring Cloud Zipkin

〇、虚拟机中docker安装elasticsearch 、Kibana、Logstash elasticsearch导入中文分词器 Logstash修改es数据库ip及创建索引名配置 一、elasticsearch数据库的结构 和mysql作比较&#xff0c;mysql中的数据库的二维表相当于es数据库的index索引结构&#xff1b;mysql数据库的二…

大数据处理从零开始————4.认识HDFS分布式文件系统

1.分布式文件系统HDFS 1.1 认识HDFS 当单台服务器的存储容量和计算性能已经无法处理大文件时&#xff0c;分布式文件系统应运而生。什么是分布式系统&#xff0c;分布式系统是由多个独立的计算机或节点组成的系统&#xff0c;这些计算机通过网络连接&#xff…

Mysql(五) --- 数据库设计

文章目录 前言1.范式1.1.第一范式1.1.1 定义1.1.2.例子 1.2.第二范式1.2.1 定义1.2.2 例子1.2.3.不满足第二范式可能会出现的问题 1.3.第三范式1.3.1 定义2.3.2 示例 2. 设计过程3. 实体-关系图3.1 E-R图的基本组成3.2 关系的类型3.2.1 一对一关系(1:1)3.2.2 ⼀对多关系(1:N)3.…

paimon,基础查询语句测试

基础设置 -- 创建catalog/加载catalog&#xff0c;如果这个catalog已经存在就不会创建&#xff0c;自动加载元数据信息CREATE CATALOG fs_paimon_catalog WITH ( type paimon, warehouse hdfs://wsl01:8020/paimon/catalog ); -- 使用catalog use catalog fs_paimon_catalog…

Java虚拟机(JVM)

目录 内存区域划分堆&#xff08;Heap&#xff09;方法区&#xff08;Method Area&#xff09;程序计数器&#xff08;Program Counter Register&#xff09;虚拟机栈&#xff08;VM Stack&#xff09;本地方法栈&#xff08;Native Method Stack&#xff09; 类加载的过程类加…

[C++]使用纯opencv部署yolov11-seg实例分割onnx模型

【算法介绍】 在C中使用纯OpenCV部署YOLOv11-seg进行实例分割是一项具有挑战性的任务&#xff0c;因为YOLOv11通常是用PyTorch等深度学习框架实现的&#xff0c;而OpenCV本身并不直接支持加载和运行PyTorch模型。然而&#xff0c;可以通过一些间接的方法来实现这一目标&#x…

运维工具之ansible

Ansible 1.什么是ansible? ​ ansible是基于ssh架构的自动化运维工具&#xff0c;由python语言实现&#xff0c;通过ansible可以远程批量部署等。 2.部署前提 ​ 控制端需要安装ansible,被控制端要开启ssh服务&#xff0c;并允许远程登录&#xff0c;被管理主机需要安装py…

卸载PLSQL及标准卸载流程

目录 1. 卸载PLSQL2. 删除注册表3. 删除数据信息 1. 卸载PLSQL 等待进度条走完 2. 删除注册表 regedit 右击删除 3. 删除数据信息 由于AppData是隐藏文件&#xff0c;需要勾选隐藏的项目。 重启电脑&#xff0c;PLSQL就卸载成功了。

浏览器和客户端结合的erp系统,java控制浏览器操作自动登录,socket客户端通信进行表单赋值

java做一个toB的客户端操作系统&#xff0c;客户端和web的结合&#xff1b; 主要是使用java编写客户端代码&#xff0c;采用selenium控制浏览器&#xff0c;主要是用到selenium自动化测试的功能&#xff1b; javaEE 项目调用 selenium使用谷歌控件chromedriver.exe控制浏览器…