Java设计模式 —— 【结构型模式】适配器模式(类的适配器、对象适配器、接口适配器)详解

news2024/12/20 23:41:44

文章目录

  • 基本介绍
  • 一、类的适配器
  • 二、对象适配器
  • 三、接口适配器
  • 总结


基本介绍

生活中有很多例子:

  • 不同国家的插座接口不同,需要转换器;
  • 家用电源220V,手机只接受5V充电,需要转换器;
  • 读卡器,拓展坞。。。

在这里插入图片描述
定义:

​ 适配器模式的主要作用是将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。

​ 适配器模式分为类适配器模式和对象适配器模式,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。

结构:

适配器模式(Adapter)包含以下主要角色:

  • 目标(Target)接口: 当前系统业务所期待的接口,它可以是抽象类或接口;
  • 适配者(Adaptee)类: 它是被访问和适配的现存组件库中的组件接口;
  • 适配器(Adapter)类: 它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

一、类的适配器

实现方式:定义一个适配器类来实现当前系统的业务接口,同时又继承现有组件库中已经存在的组件。

【例】手机充电器

家用电源220V,手机只接受5V充电,要想给手机充电,我们得需要一个转换器。

在这里插入图片描述
家用电源【适配者类】:

public class Voltage220V {
    public Integer output22V() {
        return 220;
    }
}

目标接口:

//充电器接口
public interface IVoltage5V {
    Integer output5V();
}

//给个实现类
public class Voltage5V implements IVoltage5V {

    @Override
    public Integer output5V() {
        return 5;
    }
}

适配器类:

public class VoltageAdapter extends Voltage220V implements IVoltage5V {

    @Override
    public Integer output5V() {
        return 5;
    }
}

手机类:

public class Phone {
    public void charging(IVoltage5V iVoltage5V) {
        if(iVoltage5V.output5V() == 5) {
            System.out.println("电压5V, 正在充电。。。");
        } else {
            System.out.println("只能使用5V电压充电。。。");
        }
    }
}

测试:

public class Client {
    public static void main(String[] args) {
        Phone phone = new Phone();
        System.out.println("===直接使用5V电源充电===");
        phone.charging(new Voltage5V());
        System.out.println("===使用类适配器充电===");
        phone.charging(new VoltageAdapter());
    }
}

在这里插入图片描述
小结:

  1. Java 是单继承机制,所以类适配器需要继承src一个缺点,因为这要求dst必须是接口,有一定局限性;
  2. src类的方法在 Adapter 中都会暴露出来,也增加了使用的成本;
  3. 由于其继承了 src 类,所以它可以根据需求重写 src 类的方法,使得 Adapter 的灵活性增强了。

二、对象适配器

  1. 对象适配器模式可釆用将现有组件库中已经实现的组件引入适配器类中,该类同时实现当前系统的业务接口;
  2. 基本思路和类的适配器模式相同,只是将 Adapter 类作修改,不是继承 src 类,而是持有 src 类的实例,以解兼容性的问题。 即:持有 src 类,实现 dst 类接口,完成 src -> dst 的适配;
  3. 根据“合成复用原则”,在系统中尽量使用关联关系(聚合)来替代继承关系;
  4. 对象适配器模式是适配器模式常用的一种。

使用对象适配器将上述案例做以修改后,UML类图为:

在这里插入图片描述
家用电源【适配者类】:

public class Voltage220V {
    public Integer output220V() {
        return 220;
    }
}

目标接口:

public interface IVoltage5V {
    Integer output5V();
}

public class Voltage5V implements IVoltage5V {

    @Override
    public Integer output5V() {
        return 5;
    }
}

适配器类:

public class VoltageAdapter implements IVoltage5V {
    private Voltage220V voltage220V;

    public VoltageAdapter(Voltage220V voltage220V) {
        this.voltage220V = voltage220V;
    }

    @Override
    public Integer output5V() {
        //适配规则
        Integer v220 = voltage220V.output220V();
        return v220 / 44;
    }
}
public class Phone {
    public void charging(IVoltage5V iVoltage5V) {
        System.out.println("正在充电, 电压" + iVoltage5V.output5V() + "V");
    }
}

测试:

public class Demo2 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        System.out.println("===直接使用5V电源充电===");
        phone.charging(new Voltage5V());
        System.out.println("===使用对象适配器充电===");
        phone.charging(new VoltageAdapter(new Voltage220V()));
    }
}

在这里插入图片描述

  1. 对象适配器和类适配器其实算是同一种思想,只不过实现方式不同。根据合成复用原则,使用组合替代继承,所以它解决了类适配器必须继承src的局限性问题,也不再要求 dst必须是接口;
  2. 使用成本更低,更灵活。

三、接口适配器

  1. 适配器又叫缺省适配器模式;
  2. 核心思路:当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求;
  3. 适用于一个接口不想使用其所有的方法的情况。
    在这里插入图片描述

总结

结构:

  • 类适配器:以类给到适配器,在 Adapter 里,就是将 src 当做类,继承;
  • 对象适配器:以对象给到适配器,在 Adapter 里,将 src 作为一个对象,持有;
  • 接口适配器:以接口给到适配器,在 Adapter 里,将 src 作为一个接口,实现。

优点:

  • 适配器模式最大的作用还是将原本不兼容的接口融合在一起工作;

  • 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构;

  • 增加了类的透明性和复用性,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用;

  • 灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”;

  • 对象适配器避免了但继承的缺点,可以把多个不同的适配者适配到同一个目标。

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

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

相关文章

游泳溺水识别数据集,对9984张原始图片进行YOLO,COCO JSON, VOC XML 格式的标注,平均识别率在91.7%以上

游泳溺水识别数据集: 对9984张原始图片进行YOLO,COCO JSON, VOC XML 格式的标注,平均识别率在91.7%以上 ,可识别泳池或者水库中是否有人溺水。 数据集分割 训练组98% 9818图片 有效集%…

满足更多业务需求:HZERO平台可视化大屏功能升级

前言 报表平台 报表平台是一款全面的数据可视化和报表生成工具,该平台支持多种数据源类型,包括Oracle、MySQL、HIVE等主流数据库及非关系型数据库,通过标准SQL、脚本SQL、API等多种方式灵活配置数据集,满足复杂数据结构需求。还…

Linux下部署MySQL8.0集群 - 主从复制(一主两从)

目录 一、部署前准备 1、查看系统信息 # 查看系统版本 cat /etc/red* # 查看系统位数 getconf LONG_BIT[rootlocalhost ~]# cat /etc/red* CentOS Linux release 7.5.1804 (Core) [rootlocalhost ~]# getconf LONG_BIT 642、下载对应安装包 进入MySQL官网:https:…

web3跨链桥协议-Nomad

项目介绍 Nomad是一个乐观跨链互操作协议。通过Nomad协议,Dapp能够在不同区块链间发送数据(包括rollups),Dapp通过Nomad的合约和链下的代理对跨链数据、消息进行验证、传输。其安全通过乐观验证机制和欺诈证明制约验证者实现&…

【CSS in Depth 2 精译_080】 13.1:CSS 渐变效果(中)——不同色彩空间的颜色插值算法在 CSS 渐变中的应用

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第四部分 视觉增强技术 ✔️【第 13 章 渐变、阴影与混合模式】 ✔️ 13.1 渐变 ✔️ 13.1.1 使用多个颜色节点(上)13.1.2 颜色插值方法(中) ✔️13.1…

讯飞智文丨一键生成WordPPT

在当今数字化办公的浪潮中,Word和PPT已经成为职场人士日常工作的标配工具。然而,面对繁琐的内容编辑和格式调整任务,如何提升效率成了每个人的追求。而讯飞智文,一款结合人工智能技术的文字处理与演示文稿工具,正逐渐成…

Android Studio的笔记--BusyBox相关

BusyBox 相关 BusyBoxandroid上安装busybox和使用示例一、下载二、移动三、安装和设置环境变量四、使用 busybox源码下载和查看 BusyBox BUSYBOX BUSYBOX链接https://busybox.net/ 点击链接后如图 点击左边菜单栏的Get BusyBix中的Download Source 跳转到busybox 的下载源码…

【机器学习】机器学习的基本分类-强化学习(Reinforcement Learning, RL)

强化学习(Reinforcement Learning, RL)是一种基于试错的方法,旨在通过智能体与环境的交互,学习能够最大化累积奖励的策略。以下是强化学习的详细介绍。 强化学习的核心概念 智能体(Agent) 执行动作并与环境…

博世智驾新动力:Apache DolphinScheduler如何征服数据处理挑战

视频及PPT等相关资料:点击查看 讲师介绍 陶超权,博世智驾(中国)后端工程师,负责数据处理和数据调度方面工作,在智能驾驶数据处理领域具有丰富的实践经验。在2024年12月Apache DolphinScheduler社区线上交流…

令牌(token)+加密(加盐)

目录 一,令牌技术 1,不使用session的原因: 2,有两种解决方案: (1)服务器层面的 (2)客户端层面的(JWT令牌) 生成签名: 生成jwt令牌: 验证令牌是否合法: (3)令牌实际运用 二,加密加盐: 进行加密: 进行验证: 一,令牌技术 1,不使用session的原因: 登录页面,用户会将密…

Flask入门:打造简易投票系统

目录 准备工作 创建项目结构 编写HTML模板 编写Flask应用 代码解读 进一步优化 结语 Flask,这个轻量级的Python Web框架,因其简洁和易用性,成为很多开发者入门Web开发的首选。今天,我们就用Flask来做一个简单的投票系统,让你快速上手Web开发,同时理解Flask的核心概…

阿里巴巴前端面试经验

阿里巴巴面经(新零售事业群-CBU技术部) 笔试 /*** 1. 查找落单的数字* 描述:给定一个非空的数字数组,数组有且只有一个非重复项,实现一个方法获取落单项* 示例:* getSingleNumber([1, 2, 1, 2, 0]); // 0* getSingle…

指针的深入讲解

本章重点: 字符指针数组指针指针数组数组传参和指针传参函数指针函数指针数组指向函数指针数组的指针回调函数 我们在指针的初阶的时候主要讲了: 1.指针就是变量,用来存放地址,地址唯一标识一块内存空间 2.指针的大小是固定4个…

网络多层的协议详述

网络层 1)地址管理:制定一系列的规则,通过地址,在网络上描述出一个设备的位置 2)路由选择:网络环境比较复杂,从一个节点到另一个节点,存在很多条不同的路径,需要规划出…

Zabbix6.0升级为6.4

为了体验一些新的功能,比如 Webhook 和问题抑制等,升级个小版本。 一、环境信息 1. 版本要求 一定要事先查看官方文档,确认组件要求的版本,否则版本过高或者过低都会出现问题。 2. 升级前后信息 环境升级前升级后操作系统CentOS…

UML复习题

用例与用户的4种关系对象图和类图有什么关系:对象图是类图某一时刻的快照组件图,体现的是静态图部署图,涉及到硬件的结点,实线链接 以上都是静态图 时序图,消息先后协作图 ,谁和谁交互,对象之间的交互某一…

【MFC】多工具栏如何保存状态

MFC中的工具栏本来只有一个,如果想增加几个工具栏是比较简单,但现在一个重要的问题是,状态无法保存,导致每次打开,工具栏就会出现问题,要么偏移位置要么显示不出。 经过研究,发现是MFC框架中的…

Buck开关电源闭环控制的仿真研究15V/5V[Matlab/simulink源码+Word文档]

课题设计要求 ⑴输入直流电压(VIN):15V ⑵输出电压(VO):5.0V ⑶负载电阻:R2欧 ⑷输出电压纹波峰-峰值 Vpp≤50mV ,电感电流脉动:输出电流的10% ⑸开关频率(fs):100kHz ⑹BUCK主电路二极管的通态压降VD0.5V…

鸿蒙项目云捐助第十八讲云捐助我的页面下半部分的实现

鸿蒙项目云捐助第十八讲云捐助我的页面下半部分的实现 在一般的应用app中都会有一个“我的”页面,在“我的”页面中可以完成某些设置,也可以完成某些附加功能,如“修改密码”等相关功能。这里的鸿蒙云捐助也有一个“我的”功能页面。这里对“…

Flink2.0未来趋势中需要注意的一些问题

手机打字,篇幅不长,主要讲一下FFA中关于Flink2.0的未来趋势,直接看重点。 Flink Forward Asia 2024主会场有一场关于Flink2.0的演讲,很精彩,官方也发布了一些关于Flink2.0的展望和要解决的问题。 1.0时代和2.0时代避免…