设计模式之适配器模式(通俗易懂--代码辅助理解【Java版】)

文章目录

  • 设计模式概述
  • 1、适配器模式
  • 2、适配器模式的使用场景
  • 3、优点
  • 4、缺点
  • 5、主要角色
  • 6、代码示例
    • 1)UML图
    • 2)源代码
      • (1)定义一部手机,它有个typec口。
      • (2)定义一个vga接口。
      • (3)实现一个适配器,适配器实现方式分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。
        • 1】类的适配器模式(通过继承特性来实现适配器功能)
        • 2】对象的适配器模式(通过组合方式来实现适配器功能)
        • 3】接口的适配器模式(借助抽象类来实现适配器功能)
      • (4)定义一个显示屏,用来测试上面实现的三个适配器。
  • 7、总结

设计模式概述

创建型模式:工厂方法、抽象方法、建造者、原型、单例。
结构型模式有:适配器、桥接、组合、装饰器、外观、享元、代理。
行为型模式有:责任链、命令、解释器、迭代器、中介、备忘录、观察者、状态、策略、模板方法、访问者。
常用设计模式:
单例模式、工厂模式、代理模式、策略模式&模板模式、门面模式、责任链模式、装饰器模式、组合模式、builder模式。

1、适配器模式

  • 适配器模式(Adapter Pattern)充当两个不兼容接口之间的桥梁,属于结构型设计模式。它通过一个中间件(适配器)将一个类的接口转换成客户期望的另一个接口,使原本不能一起工作的类能够协同工作。

  • 这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

2、适配器模式的使用场景

  • 假设有一部手机,它只能接受typec口输入或输出;还有一个投影仪,投影仪只能接受vga口作为输入或输出;现在,我们需要实现手机屏幕投影到投影仪上,可以通过创建一个适配器来实现:

    • 目标接口:现有的投影仪只能接受vga口。
    • 适配者类:手机的输出口为typec口。
    • 适配器类:创建一个新的类,实现目标接口,并在内部使用适配者类来将视频信号从typec口输入,转换输出到vga口,才能和投影仪对接。

3、优点

  • 促进了类之间的协同工作,即使它们没有直接的关联。
  • 提高了类的复用性。
  • 增加了类的透明度。
  • 提供了良好的灵活性。

4、缺点

  • 过度使用适配器可能导致系统结构混乱,难以理解和维护。
  • 在Java中,由于只能继承一个类,因此只能适配一个类,且目标类必须是抽象的

5、主要角色

  • 目标接口(Target):定义客户需要的接口。
  • 适配者类(Adaptee):定义一个已经存在的接口,这个接口需要适配。
  • 适配器类(Adapter):实现目标接口,并通过组合或继承的方式调用适配者类中的方法,从而实现目标接口。

6、代码示例

1)UML图

适配器模式结构图

2)源代码

(1)定义一部手机,它有个typec口。


/*** @author jstao* 定义一个手机Phone,它有一个Typec接口。* */
public class Phone {public void typecPhone() {System.out.println("信息从Typec口的手机输出。");}
}

(2)定义一个vga接口。

/*** @author jstao* 定义一个VGA接口。* */
public interface Vga {void vgaInterface();
}

(3)实现一个适配器,适配器实现方式分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。

1】类的适配器模式(通过继承特性来实现适配器功能)
/*** * 实现一个Type-c转VGA适配器,* 适配器实现方式有三种,这是第一种实现方式。* @author jstao**/
public class Typec2Vga1 extends Phone implements Vga{@Overridepublic void vgaInterface() {// TODO Auto-generated method stubtypecPhone();System.out.println("接收到Type-c口信息,信息转换成VGA接口中...");System.out.println("信息已转换成VGA接口,显示屏可以对接。");}
}
2】对象的适配器模式(通过组合方式来实现适配器功能)

/*** * 实现一个Type-c转VGA适配器,* 适配器实现方式有三种,这是第二种实现方式。* @author jstao**/
public class Typec2Vga2 implements Vga{private Phone phone;public Typec2Vga2(Phone phone) {// TODO Auto-generated constructor stubthis.phone = phone;}@Overridepublic void vgaInterface() {// TODO Auto-generated method stubif(phone != null) {phone.typecPhone();System.out.println("接收到Type-c口信息,信息转换成VGA接口中...");System.out.println("信息已转换成VGA接口,显示屏可以对接。");}}
}
3】接口的适配器模式(借助抽象类来实现适配器功能)

定义三个接口


/*** 定义接口* @author jstao**/
public interface Target {void typec();void typec2vga();void typec2hdmi();
}

定义一个抽象类


/*** 定义一个抽象类* @author jstao**/
public abstract class Adapter implements Target{public void typec() { }public void typec2vga() { }public void typec2hdmi() { }
}

实现一个vga适配器


/*** * 实现一个VGA适配器,同理还可以实现一个HDMI适配器* 适配器实现方式有三种,这是第三种实现方式。* @author jstao**/
public class VgaAdapter extends Adapter{public void typec() {System.out.println("信息从Typec口的手机输出。");}public void typec2vga() {System.out.println("接收到Type-c口信息,信息转换成VGA接口中...");System.out.println("信息已转换成VGA接口,显示屏可以对接。");}
}

(4)定义一个显示屏,用来测试上面实现的三个适配器。


/*** 定义一个显示屏* 与适配器对接* @author jstao**/
public class Screen {public static void main(String[] args) {//第一种适配器用法System.out.println("-------------第一种适配器------------");Vga vga = new Typec2Vga1();vga.vgaInterface();//适配器将typec转换成vgaSystem.out.println("显示屏对接适配器,手机成功投影到显示屏!");//第二种适配器用法System.out.println("-------------第二种适配器------------");Typec2Vga2 typec2Vga1 = new Typec2Vga2(new Phone());typec2Vga1.vgaInterface();//适配器将typec转换成vgaSystem.out.println("显示屏对接适配器,手机成功投影到显示屏!");//第三种适配器用法System.out.println("-------------第三种适配器------------");VgaAdapter vgaAdapter = new VgaAdapter();vgaAdapter.typec();vgaAdapter.typec2vga();//适配器将typec转换成vgaSystem.out.println("显示屏对接适配器,手机成功投影到显示屏!");}
}

7、总结

  • 适配器模式在源码中的应用:

    • (1)JDK源码的IO模块用到,例如 java.io.InputStreamReader(InputStream)、java.io.OutputStreamWriter(OutputStream)。
    • (2)mybatis源码日志模块用到对象适配器模式。
  • 适配器模式将一个接口转为另外一个接口。它有三种实现方式:

    • (1)当希望将一个类转换为满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。

    • (2) 当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个Typec2Vga2 类,持有原类的一个实例,在Typec2Vga2 类的方法中,调用实例的方法就行。

    • (3)当不希望实现一个接口中所有的方法时,可以创建一个抽象类Adapter ,实现所有方法,我们写别的类的时候,继承抽象类即可。

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

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

相关文章

docker入门-快速学会docker

死记硬背一张图 镜像类似于我们是使用的虚拟机,创建虚拟机前需要下载的系统镜像文件,比如iso文件,img文件等等这样一些镜像文件。 容器可以比作正在运行中的一个虚拟机。 tar文件,tar文件类似于vm使用时的vmdk文件。通过load指…

在 Docker容器中安装 ROS-Melodic 并使用 rviz 进行图形化显示

文章目录 写在前面1. 背景描述2. 安装步骤2.1 允许本地机器上的用户或进程连接到 X server2.2 拉取 docker 镜像2.3 使用镜像osrf/ros:melodic-desktop-full创建并运行容器2.4 运行 roscore2.5 运行 rviz 参考链接 写在前面 自己的测试环境: Ubuntu20.04&#xff0…

面网易后台开发居然遇到了一个困难难度算法题

在提供面经的同学中,竟然有同学在面试网易后台研发的时候遇到了一道困难难度的算法题。 一般来说,大多数面试的算法题都是以中等难度为主,遇到困难难度的算法题也许是公司现在不缺人、也许是在选拔人才、当然也很可能是面试官其实并不想要你…

在三维可视化项目中,B/S和C/S架构该如何选择?

一、什么是B/S和C/S 在3D数据可视化中,有两种常见的架构模式:BS(Browser/Server)和CS(Client/Server) B/S模式 B/S模式是指将3D数据可视化的逻辑和处理放在服务器端,而在客户端使用浏览器进行…

前端新机部署

编辑器:vscode 下载地址 vscode常用插件 显示代码修改历史、作者等信息 GitLens Nodejs版本 Node版本管理工具 Nvm下载地址 nvm常用命令: nvm ls // 查看安装的所有node.js的版本nvm list available //查看可以安装的所有node.js版本nvm install 版本…

Linux:Ubuntu系统开启SSH服务

在Ubuntu上开启SSH服务,可以按照以下步骤进行: 1.安装OpenSSH服务 如果你还没有安装OpenSSH服务,可以使用以下命令安装: sudo apt update sudo apt install openssh-server2. 启动SSH服务 安装完成后,启动SSH服务&a…

Docker在linux系统中的下载与使用

Docker在linux系统中的下载与使用 一、docker作用,下载及安装二、docker镜像三、创建容器四、容器数据卷 一、docker作用,下载及安装 ubuntu下载安装docker 命令:在ubuntu上面执行这个命令 Docker version:查看docker是否安装成功 配置阿里云镜像加速:进入阿里云网站…

【WEB应用安全测试指南–蓝队安全测试2】--超详细-可直接进行实战!!!亲测-可进行安全及渗透测试

安全基础理论入门知识参考上一篇《WEB应用安全测试指南蓝队安全测试1》 WEB应用安全测试指南2 一、文件 I/O 类1.1、任意文件上传1.2、任意文件下载1.3、文件包含 二、接口安全类2.1、短信炸弹2.2、邮件炸弹2.3、短信内容可控2.4、邮件内容可控 三、逻辑流程类3.1、越权3.2、未…

k8s部署jenkins集群,配置集群kubernetes plugin的pod模板

先安装jenkins插件,对应的源码地址是kubernetes-plugin,以供参考。 进入节点管理,开始配置。 点击 “ configure clouds” 一、配置集群 填写k8s地址:https://kubernetes.default.svc.cluster.local 命名空间:kuberne…

Redis高并发缓存设计问题与性能优化

1、缓存设计典型问题 1.1、缓存穿透 缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,通常出于容错的考虑,如果从存储层查不到数据则不写入缓存层。 缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失…

【Python】从零到一,搭建高效Web服务器,轻松上手!Python开发者必备(文末附带源码分享)

CSDN Python源码分享:实现一个简单的Web服务器 在CSDN上,我们经常分享各种技术文章和源码,帮助开发者们不断提升自己的技能。今天,我将为大家分享一个使用Python实现的简单Web服务器源码。这个Web服务器能够处理基本的HTTP GET请…

打破常规,BD仓储物流的效能提升!

当前,随着国家战略的推进,JS与民用领域的融合不断加深,物流业也步入了军民融合的新时代。在智能仓储物流方面,JS物流的智能化进展受到了BD系统的高度关注和重视。 一、建设JS仓储物流RFID基础设施 JS物流领域引入RFID技术的基础工…

Jenkins 改成中文语言显示

Jenkins 改成中文语言显示 到系统管理 插件管理中下载如下插件接口 Localization: Chinese (Simplified) 搜索的时候用ctrlf 进行搜索,不要用Jenkins下面下的filter 只有,到系统管理Manage Jenkins下的Config System下,如下截图的位置去…

动态规划算法:14.简单多状态 dp 问题_粉刷房子_C++

题目链接:LCR 091. 粉刷房子 - 力扣(LeetCode) 一、题目解析 题目: 解析: 由题可知: 涂刷房子有三种颜色可以选,所给的二维数组中三列固定不变,分别是红、蓝、绿相邻两件房子不可…

C++基础面试题 | 什么是内存对齐?为什么需要内存对齐?

文章目录 回答重点扩展知识 回答重点 内存对齐是指计算机在访问内存时,会根据一定规则将数据存储在合适的起始地址上,通常是数据大小的整数倍。这样做可以提升CPU的访问效率,特别是在读取和写入数据时。 为什么要内存对齐?主要有…

无极低码课程【mysql windows下安装要点】

在Windows环境中安装MySQL 5.7教程 MySQL 是世界上最流行的开源关系型数据库管理系统之一。本教程将指导您在Windows操作系统上安装MySQL 5.7。 网上教程较多,这里不再详述,注意关键点即可 准备工作 下载MySQL 5.7安装包 访问 MySQL官方网站 下载MyS…

【Java面试——基础知识——Day2】

1.面向对象基础 1.1 面向对象和面向过程的区别 面向过程编程(POP):面向过程把解决问题的过程拆成一个个方法,通过一个个方法的执行解决问题。面向对象编程(OOP):面向对象会先抽象出对象&#…

“链动2+1+消费增值:用户留存新策略“

大家好,我是吴军,目前在一家以创新为核心的软件开发公司担任产品经理。今天,我将深入探讨一个经受住了时间考验且依然充满活力的商业模式——“链动21”模式,并通过一个实例及相关数据展示它如何巧妙应对用户留存与复购的挑战。 首…

vllm 部署GLM4模型进行 Zero-Shot 文本分类实验,让大模型给出分类原因,准确率可提高6%

简介 本文记录了使用 vllm 部署 GLM4-9B-Chat 模型进行 Zero-Shot 文本分类的实验过程与结果。通过对 AG_News 数据集的测试,研究发现大模型在直接进行分类时的准确率为 77%。然而,让模型给出分类原因描述(reason)后,…

使用IDEA和vecode创建vue项目并启动

一、使用IDEA创建Vue项目 一、打开IDEA下载Vue插件 打开IDEA的设置找到插件并查找到下载Vue.js这个插件 二、用IDEA创建Vue项目 新建项目并选择到Vue生成器 我这是IDEA自带的 创建项目非常迅速 端口号(默认):5173 版本是3.x 启动项目…