适配器模式(Adapter Pattern)

news2024/12/26 14:42:28

1.什么是适配器模式?

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

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。

2.适配器模式的例子

举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

3.适配器模式的优缺点

优点: 

  1. 可以让任何两个没有关联的类一起运行。
  2. 提高了类的复用。
  3. 增加了类的透明度。
  4. 灵活性好。

缺点: 

  1. 过多地使用适配器,会让系统非常零乱,不易整体进行把握。
  2. 由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。

注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。

创建一个 maven 项目 adapter
引入依赖
<dependency>
          <groupId>org.springframework</groupId>  
          <artifactId>springwebmvc</artifactId> 
          <version>5.3.4</version>
</dependency>

4.自定义适配器:

创建包 adapter,在包下创建二孔插座接口 Socket,三个插头的充电器类 Charger

cn.xs.adapter.Socket 代码如下:

public interface Socket {

        /**
        * 连接功能
        */
    default void connect() {
        System.out.println("用两个孔的插头进行连接!");
    }
        /**
        * 充电功能
        */
    void charge();
}

 cn.xs.adapter.Charger 代码如下:

public class Charger {
        /**
        * 充电
        */
    public void charge() {
        System.out.println("若已连接,进行充电!");
    }
}
1.类适配器模式
cn.xs.adapter.ChargerClassAdapter 代码:
public class ChargerClassAdapter extends Charger implements Socket {
/**
* 重新适配连接功能
*/
@Override
public void connect() {
System.out.println("用三个孔的插头进行连接!");
}
}
新建测试类进行测试:
public class TestCharge {
/**
* 测试方法
*
* @param args
*/
public static void main(String[] args) {
// 1. 类适配器
Socket adapter = new ChargerClassAdapter();
adapter.connect();
adapter.charge();
}
}
2.对象适配器模式
cn.xs.adapter.ChargerObjectAdapter 代码:
public class ChargerObjectAdapter implements Socket {
/* 声明要使用的对象 */
private Charger charger;
/**
* 实例化 Charger 对象
*
* @param charger
*/
public ChargerObjectAdapter(Charger charger) {
this.charger = charger;
}
/**
* 重新适配连接功能
*/
@Override
public void connect() {
System.out.println("用三个孔的插头进行连接!");
}
/**
* 重新适配充电功能
*/
@Override
public void charge() {
charger.charge();
}
}
测试:
/**
* 测试方法
*
* @param args
*/
public static void main(String[] args) {
// 2. 对象适配器
Charger charger = new Charger();
ChargerObjectAdapter adapter = new ChargerObjectAdapter(charger);
adapter.connect();
adapter.charge();
}
类适配器与对象适配器的区别:
类适配器使用的是继承的方式,直接继承了 Charger ,所以无法对 Charger 的子类进行适配。
对象适配器使用的是组合的方式, · 所以 Charger 及其子孙类都可以被适配。另外,对象适配器对于增加一些新行为非常方便,而且新增加的行为同时适用于所有的源。
基于组合 / 聚合优于继承的原则,使用对象适配器是更好的选择。但具体问题应该具体分析,某些情况可能使用类适配器会适合,最适合的才是最好的。
3.接口适配器模式(缺省适配模式) :
思想:为一个接口提供缺省实现,这样子类可以从这个缺省实现进行扩展,而不必从原有接口进行
扩展。
这里提供一个例子。 java.awt.KeyListener 是一个键盘监听器接口,我们把这个接口的实现类对象注 册进容器后,这个容器就会对键盘行为进行监听。
像这样:
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("喝热水能治百病?");
}
@Override
public void keyReleased(KeyEvent e) {
}
});
}

可以看到其实我们只使用到其中一个方法,但必须要把接口中所有方法都实现一遍,如果接口里方法非常多,那岂不是非常麻烦。于是我们引入一个默认适配器,让适配器把接口里的方法都实现一遍,使用时继承这个适配器,把需要的方法实现一遍就好了。java 里也为 java.awt.KeyListener 提供了这样一个适配器: java.awt.KeyAdapter

我们使用这个适配器来改改上面的代码:

public static void main(String[] args) {
JFrame frame = new JFrame();
frame.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
System.out.println("喝热水能治百病?");
}
});
}

这样不必再把每个方法都实现一遍,代码看起来简洁多了。在任何时候,如果不准备实现一个接口里的所有方法时,就可以使用“缺省适配模式制造一个抽象类,实现所有方法,这样,从这个抽象类再继承下去的子类就不必实现所有的方法,只要重写需要的方法就可以了。

适配器模式的优缺点:
优点
                1.更好的复用性:系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。
                2.更好的扩展性:在实现适配器功能的时候,可以扩展自己源的行为(增加方法),从而自然地扩展系统的功能。
缺点
                1.会导致系统紊乱:滥用适配器,会让系统变得非常零乱。
例如,明明看到调用的是A接口,其实内 部被适配成了B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。

 

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

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

相关文章

浅谈现代GNSS模拟中的软件定义架构

随着技术的迭代更新&#xff0c;GPS/GNSS模拟技术也在不断发展进步。在过去&#xff0c;想要进行GNSS仿真基本上只有一种选择&#xff1a;使用固定式或分配式的硬件进行模拟。而如今&#xff0c;带来颠覆性创新的新型软件定义架构正在迅速取代传统的定制架构&#xff0c;这种独…

7款应用最广泛的 Linux 桌面环境

多样性应该是 Linux 最好的特性之一&#xff0c;用户可以不断尝试各种喜欢和新鲜玩法与花样&#xff0c;并从中找出最适合自己的应用。无论你是 Linux 新人还是老鸟&#xff0c;层出不穷的应用和桌面环境可能都会让我们应接不暇&#xff0c;特别是尝试不同的 Linux 桌面环境&am…

基于微信小程序的国产动漫论坛小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏览器…

05- 线性回归算法 (LinearRegression) (机器学习)

线性回归算法(LinearRegression)就是假定一个数据集合预测值与实际值存在一定的误差, 然后假定所有的这些误差值符合正太分布, 通过方程求这个正太分布的最小均值和方差来还原原数据集合的斜率和截距。当误差值无限接近于0时, 预测值与实际值一致, 就变成了求误差的极小值。 fr…

你的 TypeScript 还只是用来声明 string、number……的吗?

深入TS类型 联合类型 使用|操作符将变量可能出现的数值类型连接起来&#xff0c;就是联合类型 function css(ele: Element, attr: string, value: string | number) {// value参数的类型只能是string或者number// ...... } 交叉类型 使用&操作符将多种类型合并在一起&a…

JavaSE · 常量介绍 · 变量类型转换 · 理解数值提升 · int 和 Stirng 之间的相互转换

书接上回 Java 变量介绍 我们继续学习以下内容. 四、常量字面值常量final 关键字修饰的常量五、理解类型转换int 和 long/double 相互赋值int 和 boolean 相互赋值int 字面值常量给 byte 赋值强制类型转换类型转换小结六、理解数值提升int 和 long 混合运算byte 和 byte 的运算…

你还在用CSS旧时代布局的王者:浮动float 吗?

写在前面 随着flex、grid等布局的兼容性越来越好&#xff0c;float几乎已经在大众的视野消失了&#xff0c;曾经默认的小妖精终究成为了时代的眼泪。 作为前端开发者&#xff0c;你经历过float的时代吗&#xff1f;还在用float吗&#xff1f; 一、什么是浮动&#xff1f; 首…

ccc-台大林轩田机器学习基石-hw0

文章目录1 Probability and Statistics2 Linear Algebra3.Calculus一览图hw0题目链接1 Probability and Statistics 不妨假设C(n,K)C(n,K)&#xff0c;0≤K≤NC(n, K)C(n, K) &#xff0c;0 \le K\le NC(n,K)C(n,K)&#xff0c;0≤K≤N成立&#xff0c;只需证明C(n1,K)(n1)!K!(…

list类的使用和模拟实现

目录 一、list类的介绍 二、list的使用 1.构造、拷贝构造函数和迭代器 2.数据的增删查改 三、list的部分接口实现 1.节点定义 2.list类的组织 四、list的迭代器 1.迭代器的设计思路 2.const迭代器 3.->操作符的重载 4.反向迭代器 一、list类的介绍 list就是C库…

Elasticsearch基本概念和索引原理

一、Elasticsearch是什么&#xff1f; Elasticsearch是一个基于文档的NoSQL数据库&#xff0c;是一个分布式、RESTful风格的搜索和数据分析引擎&#xff0c;同时也是Elastic Stack的核心&#xff0c;集中存储数据。Elasticsearch、Logstash、Kibana经常被用作日志分析系统&…

[CCS 2022] 皇帝没有衣服:用于网络安全的AI/ML

AI/ML for Network Security: The Emperor has no ClothesCCS 22: Proceedings of the 2022 ACM SIGSAC Conference on Computer and Communications Securityhttps://dl.acm.org/doi/abs/10.1145/3548606.3560609摘要最近的一些研究工作提出了基于机器学习&#xff08;ML&…

工业废水的种类及其处理工艺有哪些?特定目标污染物的深度去除

随着工业的迅速发展&#xff0c;工业废水的种类和数量随之增加&#xff0c;对水体的污染也日趋严重&#xff0c;威胁人类的健康和正常生活。所以工业废水的处理对于环保至关重要。 保护生态环境、更好地做好工业废水的处理&#xff0c;了解工业废水及其种类与处理非常必要。 工…

MySQL 删除数据库

使用普通用户登陆 MySQL 服务器&#xff0c;你可能需要特定的权限来创建或者删除 MySQL 数据库&#xff0c;所以我们这边使用 root 用户登录&#xff0c;root 用户拥有最高权限。 当数据库不再使用时应该将其删除&#xff0c;以确保数据库存储空间中存放的是有效数据。删除数据…

【Hello Linux】 Linux基础命令

作者&#xff1a;小萌新 专栏&#xff1a;Linux 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;介绍Linux的基础命令 Linux基础命令ls指令lsls -als -dls -ils -sls -lls -nls -Fls -rls -tls -Rls -1总结思维导图pwd指令whoami指令…

Python 条件语句

Python条件语句是通过一条或多条语句的执行结果&#xff08;True或者False&#xff09;来决定执行的代码块。可以通过下图来简单了解条件语句的执行过程:Python程序语言指定任何非0和非空&#xff08;null&#xff09;值为true&#xff0c;0 或者 null为false。Python 编程中 i…

【正点原子FPGA连载】第八章UART串口中断实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

1&#xff09;实验平台&#xff1a;正点原子MPSoC开发板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id692450874670 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html 第八章UART串口中…

【SSD 代码精读】之 数据增强(Data Augmentation)

SSD 数据增强前言1、Compose2、SSDCropping3、Resize4、ColorJitter5、ToTensor6、RandomHorizontalFlip7、Normalization8、AssignGTtoDefaultBox前言 原论文 根据原论文&#xff0c;我们需要处理的有以下&#xff1a; data_transform {"train": transforms.Com…

vue2.x中使用vuex

Vuex是什么&#xff1f; Vuex是一个专门为Vue.js应用程序开发的状态管理模式。它采用集中式存储来管理应用程序中所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。Vuex也被集成到了Vue的官方调试工具vue-devtools中&#xff0c;提供了诸如零配置…

Java:使用Java功能确保应用程序安全的方法

与添加新功能一样重要的是&#xff0c;应用程序开发人员需要开始更加重视他们设计的应用程序的安全性。毕竟&#xff0c;更多的应用程序功能意味着更多的数据驻留在应用程序中。如果没有适当的安全控制&#xff0c;这些数据很容易被入侵者窃取。Java是目前世界上最安全、最流行…

如何去阅读源码,我总结了18条心法

在聊如何去阅读源码之前&#xff0c;先来简单说一下为什么要去阅读源码&#xff0c;大致可分为以下几点原因&#xff1a;最直接的原因&#xff0c;就是面试需要&#xff0c;面试喜欢问源码&#xff0c;读完源码才可以跟面试官battle提升自己的编程水平&#xff0c;学习编程思想…