Java设计模式-结构型-适配器模式

news2024/9/20 5:31:13

Java设计模式-结构型-适配器模式

本文我们简单说下设计模式中的适配器模式。

一、概述

​ 与电源适配器相似,在适配器模式中引入了一个被称为适配器(Adapter)的包装类,而它所包装的对象称为适配者(Adaptee),即被适配的类。适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。也就是说:当客户类调用适配器的方法时,在适配器类的内部将调用适配者类的方法,而这个过程对客户类是透明的,客户类并不直接访问适配者类。因此,适配器让那些由于接口不兼容而不能交互的类可以一起工作。

适配器模式可以将一个类的接口和另一个类的接口匹配起来,而无须修改原来的适配者接口和抽象目标类接口。适配器模式定义如下:

适配器模式(Adapter Pattern):将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

所以,适配器模式比较适合以下场景:

  • (1)系统需要使用现有的类,而这些类的接口不符合系统的接口。
  • (2)使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。

二、实现方式

对象适配器模式和类适配器模式

在这里插入图片描述

  • 目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
  • 需要适配的类(Adaptee):需要适配的类或适配者类。
  • 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。

类适配器

在类适配器模式中,适配器与适配者之间是继承(或实现)关系。

  • 目标接口
/**
 * @author yuanhewei
 * @date 2024/2/18 17:44
 * @description
 */
public interface Target {

    /**
     * 请求
     */
    void request();
}
  • 具体实现类
/**
 * @author yuanhewei
 * @date 2024/2/18 18:00
 * @description
 */
public class ConcreteTarget implements Target {
    @Override
    public void request() {
        System.out.println("类适配器-ConcreteTarget: 普通的实现类,具有普通的功能!");
    }
}
  • 适配者
/**
 * @author yuanhewei
 * @date 2024/2/18 17:45
 * @description
 */
public class Adaptee {
    public void specificRequest() {
        System.out.println("类适配器-Adaptee: 需要被适配器包装的具有特殊功能的类!");
    }
}
  • 适配器
/**
 * @author yuanhewei
 * @date 2024/2/18 17:45
 * @description
 */
public class Adapter extends Adaptee implements Target{

    @Override
    public void request() {
        super.specificRequest();
    }
}
  • 测试代码
/**
 * @author yuanhewei
 * @date 2022-02-17 20:11
 */
@SpringBootTest
class ClassAdapterTest {

    @Test
    void testClassAdapter() {
        Target adapter = new Adapter();
        adapter.request();
        Target concreteTarget = new ConcreteTarget();
        concreteTarget.request();
    }
}

对象适配器

在对象适配器模式中,适配器与适配者之间是关联关系。

  • 目标接口
/**
 * @author yuanhewei
 * @date 2024/2/18 17:44
 * @description
 */
public interface Target {

    /**
     * 请求
     */
    void request();
}
  • 具体实现类
/**
 * @author yuanhewei
 * @date 2024/2/18 18:00
 * @description
 */
public class ConcreteTarget implements Target {
    @Override
    public void request() {
        System.out.println("类适配器-ConcreteTarget: 普通的实现类,具有普通的功能!");
    }
}
  • 适配者
/**
 * @author yuanhewei
 * @date 2024/2/18 17:45
 * @description
 */
public class Adaptee {
    public void specificRequest() {
        System.out.println("类适配器-Adaptee: 需要被适配器包装的具有特殊功能的类!");
    }
}
  • 适配器
/**
 * @author yuanhewei
 * @date 2024/2/18 17:45
 * @description
 */
@Service
public class Adapter implements Target {
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}
  • 测试代码
/**
 * @author yunehewei
 * @date 2022-02-17 20:11
 */
@SpringBootTest
class ObjectAdapterTest {

    @Test
    void testObjAdapter() {
        // 适配器
        Target adapter = new Adapter(new Adaptee());
        adapter.request();
        // 具体实现类
        Target concreteTarget = new ConcreteTarget();
        concreteTarget.request();
    }
}

从上面的代码可以看出,适配器必须有一个被适配的类的对象,然后通过Adapter适配器,把具有具体特殊的功能交给这个对象去实现。

在使用适配器模式时,可以使Adapter适配器通过传入的不同的Adaptee对象,实现多个不同的被适配的类的功能。当然,此时我们可以为多个被适配类提取出一个接口或抽象类。这样看起来的话,似乎对象适配器模式更加灵活一点。

参考

  • https://blog.csdn.net/lovelion/article/details/8624325
  • https://blog.csdn.net/a745233700/article/details/83628122

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

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

相关文章

架构师技能9-深入mybatis:Creating a new SqlSession到查询语句耗时特别长

开篇语录:以架构师的能力标准去分析每个问题,过后由表及里分析问题的本质,复盘总结经验,并把总结内容记录下来。当你解决各种各样的问题,也就积累了丰富的解决问题的经验,解决问题的能力也将自然得到极大的…

【Python_Zebra斑马打印机编程学习笔记(一)】实现标贴预览的两种方式

实现标贴预览的两种方式 实现标贴预览的两种方式前言一、调用 Labelary Online ZPL Viewer API 方法实现标贴预览功能1、Labelary Online ZPL Viewer API 案例介绍2、生成 PNG 格式3、Parameters 二、通过 zpl 的 label.preview() 方法实现标贴预览功能1、实现步骤2、代码示例 …

每日五道java面试题之spring篇(三)

目录: 第一题 ApplicationContext和BeanFactory有什么区别?第二题 Spring中的事务是如何实现的?第三题 Spring中什么时候Transactional会失效?第四题 Spring容器启动流程是怎样的?第五题 Spring Boot、Spring MVC 和 S…

__proto__和protype的区别

概述: prototype 函数静态属性,非实例属性,所有实例都可以继承它 __proto__ 实例属性,指向实例的原型对象,原型对象包括构造函数和protype属性 替代 现代浏览器中可以使用Object.getPrototypeOf()来替代__proto__来获取原型对象 …

主流的开发语言和开发环境介绍

个人浅见,不喜勿喷,谢谢 软件开发是一个涉及多个方面的复杂过程,其中包括选择合适的编程语言和开发环境。编程语言是软件开发的核心,它定义了程序员用来编写指令的语法和规则。而开发环境则提供了编写、测试和调试代码的工具和平台…

SQL面试题及答案

介绍 在快节奏的数据管理和信息技术世界中,导航和操作结构化数据的能力是一项非常重要的技能。SQL,即结构化查询语言,是关系数据库的基石,掌握这种语言的专业人员的需求量很大。SQL 面试在科技行业很常见,潜在的候选人会接受测试以展示他们的知识和解决问题的能力。为了帮…

【Spring】常见问题总结

目录 1. 什么是 Spring 框架? 2. 列举一些重要的Spring模块? 3. RestController vs Controller 4. Spring IOC & AOP 4.1 谈谈自己对于 Spring IoC 和 AOP 的理解 IoC AOP 4.2 Spring AOP 和 AspectJ AOP 有什么区别? 5. Spring bean 5.1…

OceanMind海睿思助力企业“数据入表”之价值实现与成本计量

2023年8月21日,财政部印发《企业数据资源相关会计处理暂行规定》(以下简称《暂行规定》),明确了数据资产会计处理适用的范围、准则、列示和披露要求。 《暂行规定》是规范企业数据资产会计处理指导性和引领性的制度文件&#xff…

微信小程序 --- wx.request网络请求封装

网络请求封装 网络请求模块难度较大,如果学习起来感觉吃力,可以直接学习 [请求封装-使用 npm 包发送请求] 以后的模块 01. 为什么要封装 wx.request 小程序大多数 API 都是异步 API,如 wx.request(),wx.login() 等。这类 API 接口…

探索无限:Sora与AI视频模型的技术革命 - 开创未来视觉艺术的新篇章

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua,在这里我会分享我的知识和经验。&#x…

解决两个MySQL5.7报错

目录 1.启动不了MySQL,报错缺少MSVCR120.dll去官网下载vcredist_x64.exe运行安装进入管理员CMD 2.本地计算机 上的 mysql 服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止,Fatal error: Can‘t open and lock privilege tables: Table ‘…

网络电视盒子哪个品牌好?达人强推口碑电视盒子推荐

电视盒子使用时容易卡顿、死机,广告植入过多,系统操作复杂,散热差,这是很多电视盒子都存在的问题,网络电视盒子哪个品牌好是大家都在讨论的话题,我这次要分享的是用户评价最好的五款电视盒子推荐给不懂如何…

操作系统-吸烟者问题

文章目录 概述问题分析如何实现小结 概述 操作系统中的吸烟者问题是一个经典的同步问题,它涉及到进程间的同步和互斥。 在这个问题中,有三个抽烟者进程和一个供应者进程。每个抽烟者需要三种材料:烟草、纸和胶水来完成吸烟的操作。三个抽烟…

http协议基础与Apache的简单介绍

一、相关介绍: 互联网:是网络的网络,是所有类型网络的母集因特网:世界上最大的互联网网络。即因特网概念从属于互联网概念。习惯上,大家把连接在因特网上的计算机都成为主机。万维网:WWW(world…

Stable Diffusion 模型分享:AstrAnime(Astr动画)

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五 下载地址 模型介绍 AstrAnime 是一个动漫模型,画风色彩鲜明,擅长绘制漂亮的小姐姐。 条目内容类型大模型…

vue中实现拖拽排序功能

npm i vuedraggable <template><div class"app-container"><!-- <div :class"canEdit ? dargBtn-lock el-icon-unlock : dargBtn-lock el-icon-lock" click"removeEvent()">{{ canEdit ? 调整 : 锁定 }}</div> --&…

Windows传文件到Linux系统(拖拽方式)

1、概述? 在平时开发过程中,可能会遇到如下场景: 在自己的Window系统中安装了VMware虚拟机,并在里面安装了Linux系统(Centos,Ubuntu,redhat等)。这个时候我们期望将window中的文件传递到Linux中,传递的过程比较的麻烦。 这个时候我们就可以借助相关工具直接拖拽完成。 …

ubuntu内核卸载重装

目录 问题1.问题复现2.可以正常启动的方式 保存快照卸载有问题的内核重装最新内核参考资料 问题 1.问题复现 ubuntu开机出现如下画面,启动不能正常启动 2.可以正常启动的方式 使用其他内核可以正常工作 保存快照 在解决之前保存快照,防止破坏时恢复 卸载有问题的内核…

Gitea提交代码自动触发Jenkins构建版本

提交代码自动触发Jenkins构建版本 1. 下载Generic Webhook Trigger 2. 配置Generic Webhook Trigger http://JENKINS_URL/generic-webhook-trigger/invoke?tokenruoyi-ui-8978456465 http://192.168.0.136:8090 为jenkisn地址&#xff0c;/generic-webhook-trigger/invoke?…

【selenium】执行 Javascript 脚本 滚动、元素的特殊操作等

某些特殊情况下&#xff0c;使用selenium的api无法操作页面元素&#xff0c;点击、滚动实现的某些功能&#xff0c;可以考虑通过执行js来完成。 为什么不用js写自动化&#xff1f;——selenium第一版是js写的&#xff0c;但js兼容性存在问题&#xff0c;所以引入webdriver 现在…