设计模式之适配器模式(通俗易懂--代码辅助理解【Java版】)

文章目录

  • 设计模式概述
  • 1、适配器模式
  • 2、适配器模式的使用场景
  • 3、优点
  • 4、缺点
  • 5、主要角色
  • 6、代码示例
    • 1)UML图
    • 2)源代码
      • (1)定义一部手机,它有个typec口。
      • (2)定义一个vga接口。
      • (3)实现一个适配器,适配器实现方式分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。
        • 1】类的适配器模式(通过继承特性来实现适配器功能)
        • 2】对象的适配器模式(通过组合方式来实现适配器功能)
        • 3】接口的适配器模式(借助抽象类来实现适配器功能)
      • (4)定义一个显示屏,用来测试上面实现的三个适配器。
  • 7、总结

设计模式概述

创建型模式:工厂方法、抽象方法、建造者、原型、单例。
结构型模式有:适配器、桥接、组合、装饰器、外观、享元、代理。
行为型模式有:责任链、命令、解释器、迭代器、中介、备忘录、观察者、状态、策略、模板方法、访问者。
常用设计模式:
单例模式、工厂模式、代理模式、策略模式&模板模式、门面模式、责任链模式、装饰器模式、组合模式、builder模式。

1、适配器模式

  • 适配器模式(Adapter Pattern)充当两个不兼容接口之间的桥梁,属于结构型设计模式。它通过一个中间件(适配器)将一个类的接口转换成客户期望的另一个接口,使原本不能一起工作的类能够协同工作。

  • 这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

2、适配器模式的使用场景

  • 假设有一部手机,它只能接受typec口输入或输出;还有一个投影仪,投影仪只能接受vga口作为输入或输出;现在,我们需要实现手机屏幕投影到投影仪上,可以通过创建一个适配器来实现:

    • 目标接口:现有的投影仪只能接受vga口。
    • 适配者类:手机的输出口为typec口。
    • 适配器类:创建一个新的类,实现目标接口,并在内部使用适配者类来将视频信号从typec口输入,转换输出到vga口,才能和投影仪对接。

3、优点

  • 促进了类之间的协同工作,即使它们没有直接的关联。
  • 提高了类的复用性。
  • 增加了类的透明度。
  • 提供了良好的灵活性。

4、缺点

  • 过度使用适配器可能导致系统结构混乱,难以理解和维护。
  • 在Java中,由于只能继承一个类,因此只能适配一个类,且目标类必须是抽象的

5、主要角色

  • 目标接口(Target):定义客户需要的接口。
  • 适配者类(Adaptee):定义一个已经存在的接口,这个接口需要适配。
  • 适配器类(Adapter):实现目标接口,并通过组合或继承的方式调用适配者类中的方法,从而实现目标接口。

6、代码示例

1)UML图

适配器模式结构图

2)源代码

(1)定义一部手机,它有个typec口。


/**
 * @author jstao
 * 定义一个手机Phone,它有一个Typec接口。
 * 
 */
public class Phone {
    public void typecPhone() {
        System.out.println("信息从Typec口的手机输出。");
    }
}

(2)定义一个vga接口。

/**
 * @author jstao
 * 定义一个VGA接口。
 * 
 */
public interface Vga {
    void vgaInterface();
}

(3)实现一个适配器,适配器实现方式分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。

1】类的适配器模式(通过继承特性来实现适配器功能)
/**
 * 
 * 实现一个Type-c转VGA适配器,
 * 适配器实现方式有三种,这是第一种实现方式。
 * @author jstao
 *
 */
public class Typec2Vga1 extends Phone implements Vga{
    @Override
    public void vgaInterface() {
        // TODO Auto-generated method stub
        typecPhone();
        System.out.println("接收到Type-c口信息,信息转换成VGA接口中...");
        System.out.println("信息已转换成VGA接口,显示屏可以对接。");
    }
}
2】对象的适配器模式(通过组合方式来实现适配器功能)

/**
 * 
 * 实现一个Type-c转VGA适配器,
 * 适配器实现方式有三种,这是第二种实现方式。
 * @author jstao
 *
 */
public class Typec2Vga2 implements Vga{

    private Phone phone;
    
    public Typec2Vga2(Phone phone) {
        // TODO Auto-generated constructor stub
        this.phone = phone;
    }
    
    @Override
    public void vgaInterface() {
        // TODO Auto-generated method stub
        if(phone != null) {
            phone.typecPhone();
            System.out.println("接收到Type-c口信息,信息转换成VGA接口中...");
            System.out.println("信息已转换成VGA接口,显示屏可以对接。");
        }
    }
}
3】接口的适配器模式(借助抽象类来实现适配器功能)

定义三个接口


/**
 * 定义接口
 * @author jstao
 *
 */
public interface Target {
    
    void typec();
    void typec2vga();
    void typec2hdmi();
}

定义一个抽象类


/**
 * 定义一个抽象类
 * @author jstao
 *
 */
public abstract class Adapter implements Target{

    public void typec() { }
    
    public void typec2vga() { }
    
    public void typec2hdmi() { }
}

实现一个vga适配器


/**
 * 
 * 实现一个VGA适配器,同理还可以实现一个HDMI适配器
 * 适配器实现方式有三种,这是第三种实现方式。
 * @author jstao
 *
 */
public class VgaAdapter extends Adapter{
    
    public void typec() {
        System.out.println("信息从Typec口的手机输出。");
    }
    
    public void typec2vga() {
        System.out.println("接收到Type-c口信息,信息转换成VGA接口中...");
        System.out.println("信息已转换成VGA接口,显示屏可以对接。");
    }
}

(4)定义一个显示屏,用来测试上面实现的三个适配器。


/**
 * 定义一个显示屏
 * 与适配器对接
 * @author jstao
 *
 */
public class Screen {
    public static void main(String[] args) {
        //第一种适配器用法
        System.out.println("-------------第一种适配器------------");
        Vga vga = new Typec2Vga1();
        vga.vgaInterface();//适配器将typec转换成vga
        System.out.println("显示屏对接适配器,手机成功投影到显示屏!");
        
        //第二种适配器用法
        System.out.println("-------------第二种适配器------------");
        Typec2Vga2 typec2Vga1 = new Typec2Vga2(new Phone());
        typec2Vga1.vgaInterface();//适配器将typec转换成vga
        System.out.println("显示屏对接适配器,手机成功投影到显示屏!");
        
        //第三种适配器用法
        System.out.println("-------------第三种适配器------------");
        VgaAdapter vgaAdapter = new VgaAdapter();
        vgaAdapter.typec();
        vgaAdapter.typec2vga();//适配器将typec转换成vga
        System.out.println("显示屏对接适配器,手机成功投影到显示屏!");
    }
}

7、总结

  • 适配器模式在源码中的应用:

    • (1)JDK源码的IO模块用到,例如 java.io.InputStreamReader(InputStream)、java.io.OutputStreamWriter(OutputStream)。
    • (2)mybatis源码日志模块用到对象适配器模式。
  • 适配器模式将一个接口转为另外一个接口。它有三种实现方式:

    • (1)当希望将一个类转换为满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。

    • (2) 当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个Typec2Vga2 类,持有原类的一个实例,在Typec2Vga2 类的方法中,调用实例的方法就行。

    • (3)当不希望实现一个接口中所有的方法时,可以创建一个抽象类Adapter ,实现所有方法,我们写别的类的时候,继承抽象类即可。

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

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

相关文章

拆解学习【无线充,EMMC,锂电池电量计,OTA】(二)

主要学习到了:无线充,EMMC,手表CPU方案,锂电池电量计,OTA。 无线充电功能是产品的核心卖点之一,充电头网通过拆解发现,手表内部使用恒玄BES2500BP智能手表单芯片解决方案,内置四核C…

图书馆自习室座位预约管理微信小程序+ssm(lw+演示+源码+运行)

摘 要 随着电子商务快速发展世界各地区,各个高校对图书馆也起来越重视.图书馆代表着一间学校或者地区的文化标志,因为图书馆丰富的图书资源能够带给我们重要的信息资源,图书馆管理系统是学校管理机制重要的一环,,面对这一世界性的新动向和新…

linux线程 | 线程的控制(二)

前言: 本节内容是线程的控制部分的第二个小节。 主要是列出我们的线程控制部分的几个细节性问题以及我们的线程分离。这些都是需要大量的代码去进行实验的。所以, 准备好接受新知识的友友们请耐心观看。 现在开始我们的学习吧。 ps:本节内容适合了解线程…

如何用AI两小时上线自己的小程序

ChatGPT这个轰动全球的产品自问世以来,已经过了将近2年的时间,各行各业的精英们如火如荼的将AI能力应用到自己生产的产品中来。 为分担人类的部分工作,AI还具有非常大的想象空间,例如对于一个程序员来说,使用AI生成快…

Redis——持久化

文章目录 Redis持久化Redis的两种持久化的策略定期备份:RDB触发机制rdb的触发时机:手动执行save&bgsave保存测试不手动执行bgsave测试bgsave操作流程测试通过配置,自动生成rdb快照RDB的优缺点 实时备份:AOFAOF是否会影响到red…

Redis:分布式 - 主从复制

Redis:分布式 - 主从复制 概念配置主从模式info replicationslave-read-onlytcp-nodelay 命令slaveof 主从结构一主一从一主多从 主从复制流程数据同步命令全量同步部分同步实时同步 节点晋升 概念 Redis的最佳应用,还是要在分布式系统中。对于非分布式…

前端优化,解决页面加载慢

问题:vue项目使用vite打包后,部署在nginx服务器上,页面上访问时很慢,发现有个js文件很大导致加载很慢 先说结论: 方式时间未优化前21s开启压缩(6级)6s去掉大依赖(flowable&#xf…

YoloV8改进策略:BackBone改进|CAFormer在YoloV8中的创新应用,显著提升目标检测性能

摘要 在目标检测领域,模型性能的提升一直是研究者和开发者们关注的重点。近期,我们尝试将CAFormer模块引入YoloV8模型中,以替换其原有的主干网络,这一创新性的改进带来了显著的性能提升。 CAFormer,作为MetaFormer框架下的一个变体,结合了深度可分离卷积和普通自注意力…

解决海外社媒风控问题的工具——云手机

随着中国企业逐步进入海外市场,海外社交媒体的风控问题严重影响了企业的推广效果与账号运营。这种背景下,云手机作为一种新型技术解决方案,正日益成为企业应对海外社媒风控的重要工具。 由于海外社媒的严格监控,企业经常面临账号流…

【计算机网络 - 基础问题】每日 3 题(三十八)

✍个人博客:https://blog.csdn.net/Newin2020?typeblog 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞…

MongoDB初学者入门教学:与MySQL的对比理解

🏝️ 博主介绍 大家好,我是一个搬砖的农民工,很高兴认识大家 😊 ~ 👨‍🎓 个人介绍:本人是一名后端Java开发工程师,坐标北京 ~ 🎉 感谢关注 📖 一起学习 &…

利用弹性盒子完成移动端布局(第二次实验作业)

需要实现的效果如下&#xff1a; 下面是首先是这个项目的框架&#xff1a; 然后是html页面的代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"wid…

基于SpringBoot+Vue+uniapp的高校教务管理小程序系统设计和实现

2. 详细视频演示 文章底部名片&#xff0c;联系我获取更详细的演示视频 3. 论文参考 4. 项目运行截图 代码运行&#xff0c;效果展示图 代码运行&#xff0c;效果展示图 代码运行&#xff0c;效果展示图 代码运行&#xff0c;效果展示图 代码运行&#xff0c;效果展示图 5. 技…

深入Semantic Kernel:插件开发与实践应用(进阶篇)

文章目录 一、引言二、开发Semantic Kernel插件三、实战3.1 时间信息插件3.2 小部件工厂插件3.3 初始化Semantic Kernel实例3.4 四个实战示例3.4.1 模型幻觉3.4.2 给模型提供时间信息3.4.3 AI自动调用函数3.4.4 AI自动调用和使用枚举 四、结论 一、引言 在上一篇入门文章《探索…

集成方案 | 借助 Microsoft Copilot for Sales 与 Docusign,加速销售流程!

加速协议信息提取&#xff0c;随时优化邮件内容~ 在当今信息爆炸的时代&#xff0c;销售人员掌握着丰富的数据资源。他们能够通过 CRM 平台、电子邮件、合同库以及其他多种记录系统&#xff0c;随时检索特定个人或组织的关键信息。这些数据对于销售沟通至关重要。然而&#x…

Halcon Blob分析提取小光斑

文章目录 算子complement 返回一个区域的补集select_region_point 选择包含指定像素的所有区域intensity 计算灰度值的均值和偏差 案例 算子 complement 返回一个区域的补集 complement(Region : RegionComplement : : )Region (输入对象)&#xff1a;这指的是输入的一个或多…

AI金融攻防赛:金融场景凭证篡改检测(DataWhale组队学习)

引言 大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年10月学习赛的AI金融攻防赛学习总结文档。本文主要讲解如何解决 金融场景凭证篡改检测的核心问题&#xff0c;以及解决思路和代码实现过程。希望…

Zookeeper快速入门:部署服务、基本概念与操作

文章目录 一、部署服务1.下载与安装2.查看并修改配置文件3.启动 二、基本概念与操作1.节点类型特性总结使用场景示例查看节点查看节点数据 2.文件系统层次结构3.watcher 一、部署服务 1.下载与安装 下载&#xff1a; 一定要下载编译后的文件&#xff0c;后缀为bin.tar.gz w…

介绍Java

Java简介 Java是一门由Sun公司&#xff08;现被Oracle收购&#xff09;在1995年开发的计算机编程语言&#xff0c;其主力开发人员是James Gosling&#xff0c;被称为Java之父。Java在被命名为“Java”之前&#xff0c;实际上叫做Oak&#xff0c;这个名字源于James Gosling望向…

非线性激活pytorch

**前置知识&#xff1a; 1、 self.sigmoid1Sigmoid() outputself.sigmoid1(input) 2、常见的非线性激活函数&#xff1a; 3、非线性激活的作用&#xff1a; 线性与非线性 线性函数&#xff1a;假设你用直线去描述波浪的形状。无论你怎么改变直线的斜率&#xff0c;结果都是…