【结构型模式】适配者模式

news2024/12/23 4:19:15

文章目录

    • 优秀借鉴
    • 1、简介
    • 2、结构
    • 3、实现方式
      • 3.1、案例引入
      • 3.2、类适配器
      • 3.3、对象适配器
      • 3.4、接口适配器
    • 4、区别对比
    • 5、适配者模式优缺点
    • 6、应用场景

优秀借鉴

  1. 黑马程序员Java设计模式详解-适配器模式概述
  2. 适配器设计模式(封装器模式)
  3. 一文彻底弄懂适配器模式(Adapter Pattern)
  4. 《深入设计模式》–亚历山大·什韦茨

1、简介

适配器模式是一种常用的结构型设计模式,核心思想是将现有的接口转换为客户端所期望的接口。它允许通过将一个接口转换为另一个接口,将不兼容的类或对象组合在一起。这种模式通常用于集成现有系统或库中不兼容的组件。

在软件开发中,我们经常会遇到由不同的团队或不同的供应商编写的代码、服务或库,这些组件可能使用不同的协议、数据格式或接口定义,因此无法直接集成在一起。为了解决这个问题,我们可以使用适配器模式来创建一个适配器,它可以将这些不兼容的组件转换为一个统一的接口,从而实现它们之间的互操作性。

2、结构

当我们使用适配器模式时,通常会涉及到以下三个角色:

  1. 目标接口(Target):该角色是所需的客户端接口,也就是客户端希望使用的接口。在适配器模式中,我们需要设计一个新的目标接口来满足客户端的需求。

  2. 适配器(Adapter):该角色是适配器模式的核心,其作用是将不兼容的接口转换为目标接口。适配器可以通过继承或组合等方式实现。

  3. 源接口(Adaptee):该角色是需要被适配的现有接口,它与目标接口不兼容,无法直接使用。在适配器模式中,我们需要将源接口适配成目标接口,以便客户端能够使用。

3、实现方式

3.1、案例引入

不知道有没有尊贵的Mac用户在想要外接显示屏时,却苦于电脑只有 type-c 口而没有视频口,这个时候就需要一个 type-c 转 HDMI 的转接器了,毕竟我们总不能把电脑拆开自己加上一个 HDMI 接口对吧,要是不小心把电脑搞坏了还得花大成本去维修。

MacBook

对于上述场景中其实就用到了一个适配器模式,对应到适配器中的三个角色分别如下:

  1. 目标接口:对应的是 HDMI 线所需要的 HDMI 接口,也就是我们希望使用的接口;
  2. 适配器:对应的是转接器,作用就是将不兼容的 type-c 接口转换成目标接口 HDMI 接口
  3. 源接口:对应的是 type-c 接口,就是电脑现有的接口,与我们希望的目标接口 HDMI 接口不兼容,无法直接使用。

3.2、类适配器

类适配器通过继承来适配两个不兼容的接口。

img

下面是使用类适配器将Type-C接口转换为HDMI接口的代码实现:

// Type-C 接口
public interface TypeC {
    void sendDisplay(String content);
}

// HDMI 接口
public interface HDMI {
    void display(String content);
}

// Type-C 到 HDMI 适配器
public class TypeCToHDMIAdapter extends MacBook implements TypeC, HDMI {
    @Override
    public void sendDisplay(String content) {
        System.out.println("Type-C 转 HDMI 适配器:" + content);
        super.sendDisplay(content);
    }

    @Override
    public void display(String content) {
        System.out.println("Type-C 转 HDMI 适配器:" + content);
        super.display(content);
    }
}

// 笔记本电脑类
public class MacBook {
    public void sendDisplay(String content) {
        System.out.println("笔记本电脑发送显示信号:" + content);
    }

    public void display(String content) {
        System.out.println("在笔记本电脑屏幕上显示:" + content);
    }
}

3.3、对象适配器

对象适配器通过组合另一个类来适配两个不兼容的接口。

img

下面是使用对象适配器将 Type-C 接口转换为 HDMI 接口的代码实现:

// Type-C 接口
public interface TypeC {
    void sendDisplay(String content);
}

// HDMI 接口
public interface HDMI {
    void display(String content);
}

// Type-C 到 HDMI 适配器
public class TypeCToHDMIAdapter implements TypeC {
    private final HDMI hdmi;

    public TypeCToHDMIAdapter(HDMI hdmi) {
        this.hdmi = hdmi;
    }

    @Override
    public void sendDisplay(String content) {
        System.out.println("Type-C 转 HDMI 适配器:" + content);
        hdmi.display(content);
    }
}

// HDMI 接口实现类
public class HDMIImpl implements HDMI {
    @Override
    public void display(String content) {
        System.out.println("在 HDMI 屏幕上显示:" + content);
    }
}

3.4、接口适配器

接口适配器通过一个抽象类来适配多个不兼容的接口。在 Java 中,可以使用抽象类和默认方法来实现适配器。

接口适配器

下面是使用接口适配器将 Type-C 接口转换为 HDMI 接口的代码实现:

// Type-C 接口
public interface TypeC {
    void sendDisplay(String content);
}

// HDMI 接口
public interface HDMI {
    void display(String content);
}

// 抽象适配器类
public abstract class TypeCToHDMIAdapter implements TypeC, HDMI {
    @Override
    public void sendDisplay(String content) {
        System.out.println("Type-C 转 HDMI 适配器:" + content);
    }

    @Override
    public void display(String content) {
        System.out.println("Type-C 转 HDMI 适配器:" + content);
    }
}

// 笔记本电脑类
public class Laptop extends TypeCToHDMIAdapter {
    @Override
    public void sendDisplay(String content) {
        System.out.println("笔记本电脑发送显示信号:" + content);
        super.sendDisplay(content);
    }

    @Override
    public void display(String content) {
        System.out.println("在笔记本电脑屏幕上显示:" + content);
        super.display(content);
    }
}

4、区别对比

类适配器、对象适配器、接口适配器都是适配器模式的实现方式,它们的目的是将一个类或接口转换成另一个类或接口,以满足不同的业务需求。它们之间的联系和区别如下:

  1. 类适配器:类适配器通过继承待适配类和实现目标接口的方式,来实现对待适配类的适配。具体来说,在适配器中包含了待适配类的实例,并实现了目标接口的方法,以便客户端调用。这种方式可以在不改变已有代码的情况下进行适配,但只能适配单个待适配类。
  2. 对象适配器:对象适配器通过组合待适配类的实例和实现目标接口的适配器类的方式,来实现对待适配类的适配。具体来说,在适配器中包含了待适配类的实例,并通过实现目标接口的方式,将待适配类的方法委托给适配器来实现。这种方式可以适配多个待适配类,而且更加灵活,因为可以在运行时动态设置待适配类的实例。
  3. 接口适配器:接口适配器通过定义一个抽象适配器类,实现目标接口的所有方法,并将它们设置成空方法。待适配类只需要实现需要的方法即可,避免了实现不必要的方法,也使得适配器更加灵活。
特点类适配器对象适配器接口适配器
实现方式继承组合抽象类
适配范围单个类多个类多个方法
灵活性中等
对待适配类的影响

5、适配者模式优缺点

适配器模式是一种常用的设计模式,它可以将一个类或接口转换成另一个类或接口,以满足不同的业务需求。适配器模式有以下优缺点:

优点

  1. 提高代码复用性:适配器模式可以重用已有的代码,减少代码量;
  2. 提高系统的灵活性:适配器模式可以使得系统更加灵活,易于扩展和维护;
  3. 降低耦合度:适配器模式可以将不同的模块之间解耦,使得各个模块之间的依赖关系更加简单明了;
  4. 可以适配多个类或接口:不同的适配器实现方式可以适配多个类或接口,提高代码的可复用性。

缺点

  1. 增加代码复杂性:适配器模式需要增加新的适配器类或方法,会增加代码的复杂性;
  2. 可能会造成性能损失:适配器模式可能会引入额外的开销,例如对象适配器需要组合待适配类的实例对象;
  3. 不易理解:适配器模式可能会使代码结构变得复杂,不易于阅读和理解。
优点缺点
提高代码复用性增加代码复杂性
提高系统的灵活性可能会造成性能损失
降低耦合度不易理解
可以适配多个类或接口

6、应用场景

适配器模式是一种常用的设计模式,主要应用于以下场景:

  1. 处理旧接口与新接口的兼容性问题:当系统中的某个组件需要调用另一个组件的接口时,如果这两个组件的接口不兼容,可以使用适配器模式将旧接口转换成新接口;
  2. 重用已有的代码:适配器模式可以重用现有的代码,减少代码量,提高代码的可复用性;
  3. 构建抽象接口:适配器模式可以将多个类或接口适配成一个抽象接口,使得客户端只需要针对抽象接口编程,而不需要关注具体的实现细节;
  4. 隐藏不必要的接口:适配器模式可以隐藏一些不必要的接口,避免客户端直接访问实现类的方法,提高代码的安全和稳定性;
  5. 适配不同的数据格式:适配器模式可以适配不同的数据格式,例如将 XML 数据转换成 JSON 格式。

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

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

相关文章

页眉怎么添加【节】,设置不同章节不同页眉

文章目录前言添加【节】,设置不同内容总结前言 大家写文档或者论文的时候可能会需要:不同章节页眉展示不同的内容 然而,在双击页眉进行编辑的时候却发现几个章节的页眉一起被修改了: 会出现文章与页眉不同步的情况&#xff0c…

idea使用Junit

文章目录 idea使用JunitJunit配置常用注解常用于测试的断言方法后续idea使用Junit 对项目使用Junit主要有两个步骤: 添加Junit依赖,即添加Junit jar包使用JunitJunit配置 方法一:idea自带的快捷方法 对要测试的类的方法,在该类中,右键鼠标呼出菜单,选择Generate,快捷…

简单的回顾Linux

linux命令ls会显示出文件的颜色, 系统约定的默认颜色含义如下: 白色:表示普通文件 蓝色:表示目录 绿色:表示可执行文件 红色:表示压缩文件 浅蓝色:链接文件 主要是使用ln命令建立的文件 红色闪烁:表示链接的…

Java实现打印杨辉三角形,向左、右偏的平行四边形这三个图形代码程序

目录 前言 一、打印杨辉三角形 1.1运行流程(思想) 1.2代码段 1.3运行截图 二、向左偏的平行四边形 1.1运行流程(思想) 1.2代码段 1.3运行截图 三、向右偏的平行四边形 1.1运行流程(思想) 1.2代…

inplace-operation-error 【已解决】

最近在搞CT医学图像分割模型的领域泛化优化,结果就出现了报错: 关于这个问题stackoverflow上有非常多的讨论,可以过去围观: 指路:中文版stackoverflow - 堆栈内存溢出 (stackoom.com) Stack Overflow - Where Develo…

UNET-RKNN分割眼底血管

前言 最近找到一个比较好玩的Unet分割项目,Unet的出现就是为了在医学上进行分割(比如细胞或者血管),这里进行眼底血管的分割,用的backbone是VGG16,结构如下如所示(项目里面的图片,借用的!借用标记出处&…

C语言函数大全--h开头的函数

C语言函数大全 本篇介绍C语言函数大全–h开头的函数或宏 1. hypot,hypotf,hypotl 1.1 函数说明 函数声明函数功能double hypot(double x, double y);计算直角三角形的斜边长(double)float hypotf (float x, float y);计算直角…

UPA/URA双极化天线的协方差矩阵结构

文章目录UPA的阵列响应向量(暂不考虑双极化天线)UPA阵列响应:从单极化天线到双极化天线UPA双极化天线的协方差矩阵结构参考文献UPA的阵列响应向量(暂不考虑双极化天线) 下图形象描述了UPA阵列的接收信号 UPA阵列的水平…

【springcloud 微服务】Spring Cloud 微服务网关Gateway使用详解

目录 一、微服务网关简介 1.1 网关的作用 1.2 常用网关 1.2.1 传统网关 1.2.2 云原生网关 二、gateway网关介绍 2.1 问题起源 2.2 引发的问题 2.2.1 重复造轮子 2.2.2 调用低效 2.2.3 重构复杂 2.3 gateway改进 三、Spring Cloud Gateway 介绍 3.1 Gateway 概述 …

【JSON学习笔记】3.JSON.parse()及JSON.stringify()

前言 本章介绍JSON.parse()及JSON.stringify()。 JSON.parse() JSON 通常用于与服务端交换数据。 在接收服务器数据时一般是字符串。 我们可以使用 JSON.parse() 方法将数据转换为 JavaScript 对象。 语法 JSON.parse(text[, reviver])参数说明: text:必需&…

Angular可视化指南 - 用Kendo UI图表组件创建数据可视化

Kendo UI for Angular是专业级的Angular UI组件库,不仅是将其他供应商提供的现有组件封装起来,telerik致力于提供纯粹高性能的Angular UI组件,而无需任何jQuery依赖关系。无论您是使用TypeScript还是JavaScript开发Angular应用程序&#xff0…

【机器学习(二)】线性回归之梯度下降法

文章目录专栏导读1、梯度下降法原理2、梯度下降法原理代码实现3、sklearn内置模块实现专栏导读 ✍ 作者简介:i阿极,CSDN Python领域新星创作者,专注于分享python领域知识。 ✍ 本文录入于《数据分析之术》,本专栏精选了经典的机器…

1漏洞发现

漏洞发现-操作系统之漏洞探针类型利用修复 一、操作系统漏洞思维导图 相关名词解释: CVSS(Common Vulnerability Scoring System,即“通用漏洞评分系统”) CVSS是安全内容自动化协议(SCAP)的一部分通常C…

rockchip rk3588添加uvc及uvc,adb的复合设备

软硬件环境: 软件基础:我目前拿到的rk3588 sdk :gitwww.rockchip.com.cn:2222/Android_S/rk3588- manifests.git硬件基础:RK3588 LP4X EVB uvc_app: 从rv1126 sdk中rv1126_sdk/rv1126/external/uvc_app 目录移植而来。移植后&…

能翻译大量文字的软件-正规的翻译软件

复制自动翻译软件是一种能够复制并自动翻译文本的工具。当您阅读某一种语言的文本时,这种软件可以快速识别并翻译出来,以方便您更好地理解内容。与其他翻译软件不同的是,复制自动翻译软件可以直接在游览网站的过程中,直接对用户正…

【C++】命名空间,缺省参数,函数重载,引用,内联函数

目录1. 命名空间2. 输入输出3. 缺省参数4. 函数重载为什么C支持函数重载?5. 引用5.1 引用作函数参数(输出型参数)5.2 作函数的返回值关于函数的返回值:5.3 引用权限关于类型转换:5.4 引用和指针6. 内联函数6.1 C推荐的…

【千题案例】TypeScript获取两点之间的距离 | 中点 | 补点 | 向量 | 角度

我们在编写一些瞄准、绘制、擦除等功能函数时,经常会遇到计算两点之间的一些参数,那本篇文章就来讲一下两点之间的一系列参数计算。 目录 1️⃣ 两点之间的距离 ①实现原理 ②代码实现及结果 2️⃣两点之间的中点 ①实现原理 ②代码实现及结果 3…

JUC结构

JUC是java.util.concurrent包的简称在Java5.0添加,目的就是为了更好的支持高并发任务。让开发者进行多线程编程时减少竞争条件和死锁的问题!进程与线程的区别:进程 : 一个运行中的程序的集合; 一个进程往往可以包含多个线程,至少包含一个线程…

count、sum、avg、max、min函数MySQL数据库 - 使用聚合函数查询(头歌实践教学平台)

文章目的初衷是希望学习笔记分享给更多的伙伴,并无盈利目的,尊重版权,如有侵犯,请官方工作人员联系博主谢谢。 目录 第1关:COUNT( )函数 任务描述 相关知识 COUNT()函数基本使用 编程要求 第2关:SUM(…

3.Java运算符

Java运算符 运算符基本分为六类:算数运算符、赋值运算符、关系运算符、逻辑运算符、位运算符、三元(条件)运算符。 一、算术运算符 算数运算符,是指在Java运算中,计算数值类型的计算符号,既然是操作数值…