Java设计模式:适配器模式的三种形式(五)

news/2024/7/27 7:29:59/文章来源:https://blog.csdn.net/qq_26664043/article/details/136436946

在这里插入图片描述

码到三十五 : 个人主页

心中有诗画,指尖舞代码,目光览世界,步履越千山,人间尽值得 !


适配器模式用于将一个类的接口转换为客户端所期望的另一个接口,以实现不兼容接口之间的协作。它像电器插头转换器一样,解决接口不匹配的问题。它有三种形式:类适配器通过继承与实现完成适配,对象适配器通过组合与实现进行适配,而接口适配器则为接口提供默认实现以简化适配。无论哪种方式,目标都是使不兼容的接口能够协同工作,提高代码灵活性和可复用性,降低系统间耦合度。适配器模式广泛应用于旧代码改造、系统升级及跨平台开发等场景。

[参见]:

Java设计模式:核心概述(一)

Java设计模式:单例模式之六种实现方式详解(二)

Java设计模式:工厂模式之简单工厂、工厂方法、抽象工厂(三)

Java设计模式:建造者模式之经典与流式的三种实现(四)

目录

    • 一、什么是适配器模式
      • 角色概念
      • 使用场景
    • 二、适配器模式的三种形式
      • 1. 类适配器模式(Class Adapter Pattern)
        • 代码
        • 使用场景
        • 优点
        • 缺点
      • 2. 对象适配器模式(Object Adapter Pattern)
        • 代码
        • 使用场景
        • 优点
        • 缺点
      • 3. 接口适配器模式(Interface Adapter Pattern)
        • 代码
        • 使用场景
        • 优点
        • 缺点
    • 三、注意事项
    • 四、适配器与装饰器模式的不同

一、什么是适配器模式

适配器模式(Adapter Pattern)的核心概念是将一个类的接口转换成客户期望的另一个接口,从而让原本接口不兼容的类能够合作无间。适配器模式通过引入一个适配器类来实现这种转换,适配器类通常持有源类(即被适配的类)的引用,并实现目标接口(即客户期望的接口)。客户端代码通过调用适配器类的方法来间接调用源类的方法,从而实现接口的适配。

角色概念

适配器模式的角色概念:

  1. 目标接口(Target):客户所期待的接口,也就是适配器需要实现的接口。
  2. 源类/源接口(Adaptee):已存在的类或者接口,其方法或者行为与客户所期待的接口不兼容,需要适配器来进行适配。
  3. 适配器(Adapter):适配器是适配器模式的核心,它是一个类,该类将源类/源接口的方法或行为转换为客户所期待的接口的方法或行为。适配器通过持有源类/源接口的引用,并在其实现的目标接口方法中调用源类/源接口的方法来实现适配。

使用场景

  • 当你想使用一个已经存在的类,但其接口不符合你的需求时,你可以使用适配器模式。
  • 当你想要创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作时,你可以使用适配器模式。例如,在Android开发中,Adapter就是一个典型的适配器模式的应用,它使得ListView等UI组件可以与各种数据源进行协作。
  • 当你需要一个统一的输出接口,而输入类型不可预知时,你可以使用适配器模式。这样,你可以通过适配器将各种输入类型转换为统一的输出接口。

在这里插入图片描述


二、适配器模式的三种形式

适配器模式主要分三种:类适配器模式、对象适配器模式、接口适配器模式(默认适配器模式)。

下面将给出代码,并简要说明它们的使用场景以及各自的优缺点。

1. 类适配器模式(Class Adapter Pattern)

代码
// 源类(Adaptee)
public class Adaptee {public void specificRequest() {System.out.println("源类特有请求");}
}// 目标接口(Target)
public interface Target {void request();
}// 类适配器(继承源类,实现目标接口)
public class ClassAdapter extends Adaptee implements Target {@Overridepublic void request() {specificRequest(); // 调用源类的方法System.out.println("类适配器对请求进行了适配");}
}// 客户端代码
public class Client {public static void main(String[] args) {Target target = new ClassAdapter();target.request();}
}
使用场景

当你想将一个已经存在的类适配到一个不兼容的接口,并且这个类的方法在适配器中都会被用到时,可以使用类适配器模式。

优点
  • 适配器可以覆盖源类的方法,提供更灵活的行为控制。
  • 代码结构比较简单,只需继承源类和实现目标接口。
缺点
  • 由于Java不支持多重继承,如果源类已经是某个类的子类,则无法使用类适配器模式。
  • 适配器与源类紧密耦合,源类的任何改变都可能影响适配器。

2. 对象适配器模式(Object Adapter Pattern)

代码
// 源类(Adaptee,与类适配器模式中的相同)// 目标接口(Target,与类适配器模式中的相同)// 对象适配器(持有源类的引用,实现目标接口)
public class ObjectAdapter implements Target {private Adaptee adaptee;public ObjectAdapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {adaptee.specificRequest(); // 调用源类的方法System.out.println("对象适配器对请求进行了适配");}
}// 客户端代码
public class Client {public static void main(String[] args) {Adaptee adaptee = new Adaptee();Target target = new ObjectAdapter(adaptee);target.request();}
}
使用场景

当你想将一个已经存在的类适配到一个不兼容的接口,但你不想使用继承或者源类的方法在适配器中不会被全部用到时,可以使用对象适配器模式。

优点
  • 适配器与源类的关系由继承变为关联,更加灵活。
  • 可以适配多个源类到同一个目标接口,只需在适配器中更换源类对象即可。
缺点
  • 需要额外创建适配器类来适配源类和目标接口。
  • 相比类适配器模式,对象适配器模式的性能可能略低,因为涉及到对象的创建和引用。

3. 接口适配器模式(Interface Adapter Pattern)

代码
// 目标接口(有很多方法)
public interface Target {void method1();void method2();// ... 其他方法
}// 抽象适配器类(实现目标接口,提供所有方法的默认实现)
public abstract class AbstractAdapter implements Target {@Overridepublic void method1() { /* 默认实现 */ }@Overridepublic void method2() { /* 默认实现 */ }// ... 其他方法的默认实现
}// 具体适配器类(继承抽象适配器类,重写需要的方法)
public class ConcreteAdapter extends AbstractAdapter {@Overridepublic void method1() {// 实现具体功能}
}// 客户端代码
public class Client {public static void main(String[] args) {Target adapter = new ConcreteAdapter();adapter.method1(); // 调用具体功能// adapter.method2(); 使用默认实现,如果需要的话}
}
使用场景

当一个接口有很多方法,但客户端只对其中的一部分方法感兴趣,或者想要提供一个只需要实现部分方法的默认实现时,可以使用接口适配器模式。

优点
  • 客户端可以只覆盖它感兴趣的方法,对于其他方法可以使用默认实现。
  • 减少了实现接口所需的工作量,因为大部分方法已经有了默认实现。
缺点
  • 如果需要为多个不相关的接口提供适配器,则可能需要为每个接口都创建一个抽象适配器和具体适配器,增加了系统的复杂性。
  • 当接口改变时,可能需要更新抽象适配器以提供新的默认实现。
    在这里插入图片描述

三、注意事项

  • 适配器模式不是在软件设计阶段考虑的问题,而是解决正在服役的项目的问题。也就是说,当你发现已有的类无法满足新的需求时,才考虑使用适配器模式。
  • 适配器模式实现了对原有接口的扩展,而不是修改原有接口或原有类的代码。这是设计模式的一个重要原则:开闭原则(对扩展开放,对修改封闭)。
  • 适配器模式的使用会增加系统的复杂性和理解难度,因为需要引入额外的适配器类。因此,在使用适配器模式时,需要权衡其带来的好处和增加的复杂性。
  • 适配器模式并不一定能解决所有的接口不兼容问题。在某些情况下,可能需要采用其他的设计模式或者重构代码来解决接口不兼容的问题。

四、适配器与装饰器模式的不同

与装饰器模式(Decorator Pattern)相比,适配器模式和装饰器模式都涉及到对类和接口的包装和扩展,但它们的侧重点和目的不同。

1. 侧重点不同:适配器模式主要解决的是接口不兼容的问题,它并不关注对象的功能增强,而是专注于将已有的功能通过适配器类以新的接口形式暴露给客户端。而装饰器模式则侧重于对对象的功能进行扩展和增强,它通常在不改变原有对象的基础上,动态地给对象添加一些额外的职责或行为。

2. 目的不同:适配器模式的主要目的是解决接口不兼容的问题,使得原本无法协同工作的类能够一起工作。而装饰器模式的主要目的是在不改变原有类的基础上,动态地扩展类的功能,增加类的职责。

3. 包装形式不同:适配器模式通常是通过继承或关联关系来实现接口的适配,它可能会改变原有接口的结构和形式。而装饰器模式则是通过组合关系来扩展对象的功能,它通常保持原有接口的稳定性和一致性。

4. 使用场景不同:适配器模式通常用于系统升级、代码重构等场景,当原有系统的接口无法满足新系统的需求时,可以使用适配器模式进行接口的适配。而装饰器模式则常用于需要在运行时动态地给对象添加功能或职责的场景,如Java IO流中的BufferedInputStream、BufferedReader等就是典型的装饰器模式的应用。

综上所述,适配器模式和装饰器模式虽然都涉及到对类和接口的包装和扩展,但它们的侧重点、目的、包装形式和使用场景都有所不同。在实际应用中,应根据具体的需求和场景来选择合适的设计模式。

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

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

相关文章

VIVADO使用过程中一些注意点

若要将状态改回成“synth_design Complete”,可进行如下操作: 1.清空IP缓存区数据:在Tcl Console窗口中输入“config_ip_cache ‑clear_output_repo”,此时工程中IP缓存数据被清除; 2.禁用IP缓存:在Tcl C…

混合测试写一写

题目 服务器IP地址规划:client:12.0.0.12/24,网关服务器:ens36:12.0.0.1/24、ens33:192.168.44.1/24,Web1:192.168.44.30/24,Web2:192.168.44.50/24,Nginx&am…

CSS的盒子模型:掌握网页设计的基石!

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

算法刷题day25:多路归并

目录 引言概念一、鱼塘钓鱼二、技能升级三、序列 引言 关于这个多路并归蓝桥杯考的不是很多,如果要出的话,可能模型都会差不多,因为不会出太难的题,难题基本上都是贪心、DP之类的,所以好好刷题刷熟练就行了&#xff0…

JVM-垃圾收集器G1

G1垃圾回收器 概述: 是一款面向服务器的垃圾收集器,主要针对配备多个处理器及大容量内存的机器. 以极高效率满足GC停顿时间要求的同时,还具备高吞吐量性能特征.G1保留了年轻代和老年代的概念,但不再是物理隔阂了,它们都是(可以不连…

前端javascript的DOM对象操作技巧,全场景解析

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 所属的专栏:前端泛海 景天的主页:景天科技苑 文章目录 1.js的DOM介绍2.节点元素层级关系3.通过js修改,清空节点…

Matlab|基于目标级联法的微网群多主体分布式优化调度

目录 主要内容 1.1 上层微网群模型 1.2 下层微网模型 部分程序 实现效果 下载链接 主要内容 本文复现《基于目标级联法的微网群多主体分布式优化调度》文献的目标级联部分, 建立微网群系统的两级递阶优化调度模型: 上层是微网群能量调度中心优化调度…

Awesome-Backbones-main——alexnet模型分析

AlexNet作为骨干网络相对较老,可能在复杂数据集上的表现不如一些最新的深度网络结构,如ResNet、EfficientNet等,学习率调整策略中采用了阶梯式学习率更新器,可能并不总是适合所有数据集和模型,需要根据具体情况调整学习…

vue 使用 PrintJs 实现打印pdf效果

一、print.js介绍 Print.js主要是为了帮助我们直接在应用程序中打印PDF文件,而无需离开界面,并且不使用嵌入。对于用户不需要打开或下载PDF文件的特殊情况,他们只需要打印它们。 例如,当用户请求打印在服务器端生成的报告时&…

【刷题记录】详谈设计循环队列

下题目为个人的刷题记录,在本节博客中我将详细谈论设计循环队列的思路,并给出代码,有需要借鉴即可。 题目:LINK 循环队列是线性表吗?或者说循环队列是线性结构吗? 对于这个问题,我们来看一下线…

C语言之练手题

题目1: 思路:我们定义两个变量left和right分别为数组的左端下标和右端下标。 左端下标的元素为奇数时,left继续往前走,为偶数时就停下 右端下标的元素为偶数时,right- -往回走,为奇数时停下 停下后对应的元…

云计算 3月8号 (wordpress的搭建)

项目wordpress 实验目的: 熟悉yum和编译安装操作 锻炼关联性思维,便于以后做项目 nginx 编译安装 1、安装源码包 [rootlinux-server ~]# yum -y install gcc make zlib-devel pcre pcre-devel openssl-devel [rootlinux-server ~]# wget http://nginx.…

Python 对Excel工作表中的数据进行排序

在Excel中,排序是整理数据的一种重要方式,它可以让你更好地理解数据,并为进一步的分析和报告做好准备。本文将介绍如何使用第三方库Spire.XLS for Python通过Python来对Excel中的数据进行排序。包含以下三种排序方法示例: 按数值…

WPF Border控件 基本使用

Border 基本使用 1单线效果 代码&#xff1a; <Border Grid.Row"0" BorderThickness"0,0,0,1" BorderBrush"Red" /> 说明&#xff1a; BorderThickness"0,0,0,1" 可以分别设置四条边&#xff0c;顺序是&#xff1a;左 上 右…

tcp服务器客户端通信(socket编程)

目录 1.编程流程 2.代码演示 2.1 服务器代码 2.2 客户端代码 3.注意 3.1 ping命令 3.2 netstat命令 3.3 为什么memset? 3.4 哪个会阻塞? 3.5 显示连接信息 1.编程流程 2.代码演示 2.1 服务器代码 #include <stdio.h> #include <stdlib.h> #include <…

ArmSoM Rockchip系列产品 通用教程 之 UART 使用

1. UART 简介​ Rockchip UART (Universal Asynchronous Receiver/Transmitter) 基于16550A串口标准&#xff0c;完整模块支持以下功能&#xff1a; 支持5、6、7、8 bits数据位。支持1、1.5、2 bits停止位。支持奇校验和偶校验&#xff0c;不支持mark校验和space校验。支持接…

git分布式管理-头歌实验标签

一、创建标签 任务描述 现在你已经成了项目负责人&#xff0c;由你负责发布版本&#xff0c;你需要在发布一个版本之前&#xff0c;给该版本对应的代码打上标签&#xff0c;以便于管理和标识。 本关任务&#xff1a;为最近一次提交打上标签。 相关知识 在开发过程中&#xff0c…

【论文阅读】High-Resolution Image Synthesis with Latent Diffusion Model

High-Resolution Image Synthesis with Latent Diffusion Model 引用&#xff1a; Rombach R, Blattmann A, Lorenz D, et al. High-resolution image synthesis with latent diffusion models[C]//Proceedings of the IEEE/CVF conference on computer vision and pattern re…

免费的文案二次创作软件,打造高质量原创文案

在当今数字化时代&#xff0c;内容创作已经成为企业和个人推广自身品牌、产品和服务的重要手段。然而&#xff0c;对于许多人来说&#xff0c;撰写高质量的原创文案并非易事。幸运的是&#xff0c;随着技术的发展&#xff0c;出现了许多文案二次创作免费软件&#xff0c;为那些…

基于ACM32 MCU的电动滑板车方案介绍

随着智能科技的快速发展&#xff0c;电动滑板车的驱动系统也得到了长足的发展。国内外的电动滑板车用电机驱动系统分为传统刷式电机和无刷电机两种类型。其中&#xff0c;传统的刷式电机已经逐渐被无刷电机所取代&#xff0c;无刷电机的性能和寿命都更出色&#xff0c;已成为电…