设计模式之适配器模式

目录

1、什么是适配器模式

2、为什么用适配器模式

3、适配器模式的结构

4、类适配器模式代码实现

4.1 思想

4.2 代码实现

4.3 问题分析 

5、对象适配器模式代码实现

5.1 思想

5.2 代码实现

6、适配器模式应用场景


1、什么是适配器模式

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

适配器模式能够将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
适配器模式分为类适配器模式和对象适配器模式,前者类之间的耦合度比后者高,要求程序员了解现有组件库中的相关组件的内部结构,且前者不符合我们六大软件设计原则中的“合成复用原则”,所以应用相对较少些。

2、为什么用适配器模式

举个很简单的例子:大家在之前的时候,会发现耳机孔是那种圆圆的耳机孔,但是发展到后来,大部分手机取消了这种圆圆的耳机孔(图一),取而代之的是将耳机头改为Type-C头(图二),和充电口共用一个口。但是如果我们这个时候想用那种圆圆的耳机孔的话,只能通过“转接头”(图三)来使用。这个转接头便是“适配器”思想。

图一

 图二

图三 

3、适配器模式的结构

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

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

接下来我们会利用上述例子来讲解适配器类的实现。例子:有一部手机,只支持Type-C接口的耳机,但是我们现在拥有的是圆口耳机,因此只能用转换器来使得我们的手机能够使用圆口耳机。

4、类适配器模式代码实现

4.1 思想

实现方式:定义一个适配器类来实现当前系统的业务接口,同时又继承现有组件库中已经存在的组件。

4.2 代码实现

Type-C耳机接口:

public interface TypeCEarPhone { //Type-C耳机接口
    public void type();//表名自己是什么类型
}

 Type-C口耳机的实现类:

public class TypeCEarPhoneImpl implements TypeCEarPhone { //Type-C口耳机的实现类
    @Override
    public void type() {
        System.out.println("我是Type-C口的耳机");
    }
}

 圆口耳机接口:

public interface CircularEarPhone { //圆口耳机接口
    public void type();//表名自己是什么类型
}

圆口耳机的实现类:

public class CircularEarPhoneImpl implements CircularEarPhone { //圆口耳机的实现类
    @Override
    public void type() {
        System.out.println("我是圆口的耳机");
    }
}

手机类:

public class Phone { //手机类
    public void useEarPhone(TypeCEarPhone earPhone){ //只支持Type-C接口的耳机
        earPhone.type();//表明自己现在是什么耳机类型
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        Phone phone = new Phone(); //new一个手机对象
        CircularEarPhoneImpl earPhone = new CircularEarPhoneImpl();//此时我只有一个圆口耳机
        phone.useEarPhone(earPhone); //手机来使用耳机
    }
}

大家会发现,上述代码会报错: 

因为我们手机仅支持Type-C口的,因此这里我们肯定无法使用圆口的耳机,因此这个时候就需要使用“转换器”来使得我们手机能够使用这个耳机了。

转换器类:

public class Adapter extends CircularEarPhoneImpl implements TypeCEarPhone {
    @Override
    public void type() {
        super.type();
    }
}

这个时候我们再来通过转换类使用耳机即可:

public class Test {
    public static void main(String[] args) {
        Phone phone = new Phone(); //new一个手机对象
        Adapter earPhone = new Adapter();//由于转换器类继承了耳机类,相当于耳机和转换器直接连一起了
        phone.useEarPhone(earPhone); //手机来使用耳机
    }
}

运行结果如下:

4.3 问题分析 

可见,上述我们通过“转换器”成功让我们仅支持Type-C接口的手机使用上了圆口的耳机。这种方式比较简单粗暴,直接相当于将“耳机和转换器”连接到一起使用,但是缺点很明显:耦合性太大,如果此时我们想使用的是另一个圆口耳机类,是不是就不太行了?因此我们更推荐大家使用接下来这种实现方式:对象适配器模式。当然这种方式也是更符合我们“合成复用原则”的一种实现方式。

5、对象适配器模式代码实现

5.1 思想

实现方式:对象适配器模式可釆用将现有组件库中已经实现的组件引入适配器类中,该类同时实现当前系统的业务接口。

5.2 代码实现

这里我们手机类、圆口耳机接口、圆口耳机接口实现类、Type-C耳机接口、Type-C耳机接口实现类均和上述代码一样。唯一有变化的便是适配器类。

适配器类:

public class Adapter implements TypeCEarPhone {
    private CircularEarPhone earPhone;
    public Adapter(CircularEarPhone circularEarPhone){
     earPhone=circularEarPhone;
    }
    @Override
    public void type() {
        earPhone.type();
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        Phone phone = new Phone(); //new一个手机对象
        CircularEarPhoneImpl circularEarPhone = new CircularEarPhoneImpl();//我们拥有的圆口耳机
        Adapter adapter = new Adapter(circularEarPhone);//将圆口耳机装上"转换器"
        phone.useEarPhone(adapter); //手机来使用耳机
    }
}

运行结果:

可见,这种“对象适配器模式”大大减少了我们适配器和耳机的耦合度,如果此时我们拥有的是另一种圆口类型的耳机,直接传参即可,因此我们更推荐大家使用这种适配器模式。

6、适配器模式应用场景

  • 以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致。
  • 使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

19. Unity - 2D游戏开发小记02 --- 伪透视图、2D物体碰撞、瓦片地图碰撞、素材缩放平铺

1. 伪视图 在2D游戏开发当中,当角色移动时,会发生物体与物体之间的前后遮挡。2D视图中的前后关系是由 Y 轴决定,y 值越小物体越靠前。unity的渲染应开启根据 y 值的大小进行渲染才能保证正确的遮挡效果,在菜单栏Editor–>project setting --> Graphic中按照下图方式…

C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”

C的一个大坑:菱形继承 希望这篇文章能让你理解什么是菱形继承,以及菱形继承的注意事项 单继承与多继承 单继承:一个子类只有一个直接父类时称这个继承关系为单继承 多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承…

凌恩生物美文分享|HGTree v2.0:水平基因转移数据库

水平基因转移(HGT)是指遗传物在物种间从一个相邻生物体到另一个生物体横向传递,是原核生物遗传变异的重要过程。HGT是负责塑造原核生物基因组和在自然选择中生存的驱动力之一,对原核生物的进化有很大贡献,但它会使物种进化史复杂化&#xff0…

【Linux】进程信号保存

前言 上篇博客我们了解了进程信号的概念和信号如何产生。 本篇我们将学习进程信号如何保存。 文章目录 前言一. 阻塞信号二. 递达动作三. 信号集四. 信号集操作函数结束语 一. 阻塞信号 首先我们需要一些预备知识 实际执行信号的处理动作称为信号递达(Delivery&am…

数字图像处理-绪论

数字图像处理-绪论 文章目录 前言一、闲谈二、什么是数字图像处理?2.1. 什么是数字图像?2.1.1. 可见光图像2.1.2. 不可见光图像 2.2. 什么是数字图像处理? 三、数字图像处理的前世今生3.1. 数字图像处理的前世3.2. 数字图像处理的今生 四、数…

【嵌入式系统】课程复习资料整理

【嵌入式系统】课程复习资料整理 一、绪论 1.定义 从技术的角度定义:以应用为中心、以计算机技术为基础、软件硬件可裁剪、对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。从系统的角度定义:嵌入式系统是设计完成复杂功能的硬件和软件&a…

使用crontab定时自动更新DDNS

需求说明: N1盒子的armbian系统配置好了 ipv6 的ddns,实现了域名访问本机,但是本地ipv6可能会发生变化,当发生变化后,需要手动执行指令,将新的ip与域名绑定,现在我们采用定时任务,每…

Nuvoton NK-980IOT开发板 u-boot 编译

前言 最近搭建了 Nuvoton NK-980IOT开发板 的开发编译环境,记录一下 u-boot 的 编译流程 Nuvoton NK-980IOT开发板 资源还是比较的丰富的,可以用于 嵌入式Linux 或者 RT-Thread 的学习开发 开发板上电比较的容易,两根 USB 线即可&#xff0…

计网笔记 01 概述 计算机网络体系结构、参考模型

文章目录 前言1、计网概述1.1 概念、组成、功能、分类1.1.1 概念1.1.2 计网组成1.1.2 计网分类 1.2 标准化工作及相关组织1.2.1 标准的分类 1.3 性能指标★★★1.3.1 速率相关性能指标1.3.2 时延相关指标 2、体系结构&参考模型★★★★★(对应王道视频7-10p 相当…

Android Jetpack:利用Palette进行图片取色

与产品MM那些事 新来一个产品MM,因为比较平,我们就叫她A妹吧。A妹来第一天就指出:页面顶部的Banner广告位的背景是白色的,太单调啦,人家不喜欢啦,需要根据广告图片的内容自动切换背景颜色,颜色…

基于CUDA的GPU计算PI值

访问【WRITE-BUG数字空间】_[内附完整源码和文档] 基于CUDA的GPU计算PI值。本项目使用CUDA编程模型并行计算PI值,研究GPU与CPU效率的比较,分析不同GPU线程分块对性能的影响。 异构计算试验报告 —实验1:基于CUDA的GPU计算PI值 第一部分&…

JS逆向 -- 某平台登录加密分析

一、打开网站,使用账号密码登录 账号:aiyou123.com 密码:123456 二、通过F12抓包,抓到如下数据,发现密码加密了 三、加密结果是32位,首先考虑是md5加密。 四、全局搜索pwd,点击右上角&#xf…

【ros2】ros melodic迁移到ros2 dashing过程中碰到的问题及解决方法

序言 总结踩坑经历,以利他人 1. error: forming pointer to reference type … & 报错原因: ros2回调函数的参数不能是引用形式 &,需要去除& 解决方法: 如果是指针引用,直接去除引用 void Callback(con…

javascript中的严格模式

认识严格模式: 在ECMAScript5标准中,JavaScript提出了严格模式的概念(Strict Mode): 严格模式很好理解,是一种具有限制性的JavaScript模式,从而是代码隐式的脱离了“懒散(sloppy)模…

软件测试实战,Web测试详细总结 (覆盖所有测试点),你要的都有

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

在技术圈超卷的当下,学历到底是敲门砖还是枷锁?

前言 最近,突然之间被“孔乙己文学”刷屏了,短时间内“孔乙己文学”迅速走红,孔乙己是中国文学中的一位经典人物,他的长衫被认为是他的象征之一,孔乙己的长衫折射出很多现象,既有社会的,也有教育…

Android平台播放透明视频

Android平台播放透明视频 思路 设计一种特殊的视频,它的一半内容存储alpha信息,另一半内容存储rgb信息,接着通过OpenGL获取每个像素点的alpha值和rgb值进行混合,最后出来的画面就是带有透明效果的视频了。 可以上下的分&#xf…

服务器中了勒索病毒,升级后的Malox勒索病毒特征,勒索病毒解密数据恢复

Mallox勒索病毒是网络上较为流行的勒索病毒,但是随着黑客加密技术的不断升级,Mallox勒索病毒的新升级版本Malox勒索病毒已经开始出现。Malox勒索病毒是一种最近在网络上广泛传播的恶意软件,其感染方式多种多样,主要以加密受害人的…

基于zookeeper实现分布式锁

目录 zookeeper知识点复习 相关概念 java客户端操作 实现思路分析 基本实现 初始化链接 代码落地 优化:性能优化 实现阻塞锁 监听实现阻塞锁 优化:可重入锁 zk分布式锁小结 zookeeper知识点复习 Zookeeper(业界简称zk&#xff…

Zookeeper系统模型介绍

目录 一、数据模型 二、 节点的类型 (1)持久节点 (2)持久顺序节点 (3)临时节点 (4)临时顺序节点 三、客户端命令行 (1)创建节点 (2&…