结构型模式 - 适配器模式

概述

如果去欧洲国家去旅游的话,他们的插座如下图最左边,是欧洲标准。而我们使用的插头如下图最右边的。因此我们的笔记本电脑,手机在当地不能直接充电。所以就需要一个插座转换器,转换器第1面插入当地的插座,第2面供我们充电,这样使得我们的插头在当地能使用。生活中这样的例子很多,手机充电器(将220v转换为5v的电压),读卡器等,其实就是使用到了适配器模式。

定义:

将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。

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

结构

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

  • 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。

  • 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。

  • 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

类适配器模式

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

【例】读卡器

现有一台电脑只能读取SD卡,而要读取TF卡中的内容的话就需要使用到适配器模式。创建一个读卡器,将TF卡中的内容读取出来。

类图如下:

代码如下:

//SD卡的接口
public interface SDCard {
    //读取SD卡方法
    String readSD();
    //写入SD卡功能
    void writeSD(String msg);
}

//SD卡实现类
public class SDCardImpl implements SDCard {
    public String readSD() {
        String msg = "sd card read a msg :hello word SD";
        return msg;
    }

    public void writeSD(String msg) {
        System.out.println("sd card write msg : " + msg);
    }
}

//电脑类
public class Computer {

    public String readSD(SDCard sdCard) {
        if(sdCard == null) {
            throw new NullPointerException("sd card null");
        }
        return sdCard.readSD();
    }
}

//TF卡接口
public interface TFCard {
    //读取TF卡方法
    String readTF();
    //写入TF卡功能
    void writeTF(String msg);
}

//TF卡实现类
public class TFCardImpl implements TFCard {

    public String readTF() {
        String msg ="tf card read msg : hello word tf card";
        return msg;
    }

    public void writeTF(String msg) {
        System.out.println("tf card write a msg : " + msg);
    }
}

//定义适配器类(SD兼容TF)
public class SDAdapterTF extends TFCardImpl implements SDCard {

    public String readSD() {
        System.out.println("adapter read tf card ");
        return readTF();
    }

    public void writeSD(String msg) {
        System.out.println("adapter write tf card");
        writeTF(msg);
    }
}

//测试类
public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer();
        SDCard sdCard = new SDCardImpl();
        System.out.println(computer.readSD(sdCard));

        System.out.println("------------");

        SDAdapterTF adapter = new SDAdapterTF();
        System.out.println(computer.readSD(adapter));
    }
}

类适配器模式违背了合成复用原则。类适配器是客户类有一个接口规范的情况下可用,反之不可用。

对象适配器模式

实现方式:对象适配器模式可釆用将现有组件库中已经实现的组件引入适配器类中,该类同时实现当前系统的业务接口。

【例】读卡器

我们使用对象适配器模式将读卡器的案例进行改写。类图如下:

代码如下:

类适配器模式的代码,我们只需要修改适配器类(SDAdapterTF)和测试类。

//创建适配器对象(SD兼容TF)
public class SDAdapterTF  implements SDCard {

    private TFCard tfCard;

    public SDAdapterTF(TFCard tfCard) {
        this.tfCard = tfCard;
    }

    public String readSD() {
        System.out.println("adapter read tf card ");
        return tfCard.readTF();
    }

    public void writeSD(String msg) {
        System.out.println("adapter write tf card");
        tfCard.writeTF(msg);
    }
}

//测试类
public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer();
        SDCard sdCard = new SDCardImpl();
        System.out.println(computer.readSD(sdCard));

        System.out.println("------------");

        TFCard tfCard = new TFCardImpl();
        SDAdapterTF adapter = new SDAdapterTF(tfCard);
        System.out.println(computer.readSD(adapter));
    }
}

注意:还有一个适配器模式是接口适配器模式。当不希望实现一个接口中所有的方法时,可以创建一个抽象类Adapter ,实现所有方法。而此时我们只需要继承该抽象类即可。

应用场景

  • 以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致。

  • 使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同。

JDK源码解析

Reader(字符流)、InputStream(字节流)的适配使用的是InputStreamReader。

InputStreamReader继承自java.io包中的Reader,对他中的抽象的未实现的方法给出实现。如:

public int read() throws IOException {
    return sd.read();
}

public int read(char cbuf[], int offset, int length) throws IOException {
    return sd.read(cbuf, offset, length);
}

如上代码中的sd(StreamDecoder类对象),在Sun的JDK实现中,实际的方法实现是对sun.nio.cs.StreamDecoder类的同名方法的调用封装。类结构图如下:

从上图可以看出:

  • InputStreamReader是对同样实现了Reader的StreamDecoder的封装。

  • StreamDecoder不是Java SE API中的内容,是Sun JDK给出的自身实现。但我们知道他们对构造方法中的字节流类(InputStream)进行封装,并通过该类进行了字节流和字符流之间的解码转换。

结论:

从表层来看,InputStreamReader做了InputStream字节流类到Reader字符流之间的转换。而从如上Sun JDK中的实现类关系结构中可以看出,是StreamDecoder的设计实现在实际上采用了适配器模式。

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

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

相关文章

springboot+vue开发后台增删改查

效果图 前端代码【User.vue】 <template><div class"data-container"><!--添加 start--><div class"data-header"><el-button round click"addHander" size"large" type"primary"><el-ic…

区间预测 | MATLAB实现QRBiLSTM双向长短期记忆神经网络分位数回归多输入单输出区间预测

区间预测 | MATLAB实现QRBiLSTM双向长短期记忆神经网络分位数回归多输入单输出区间预测 目录 区间预测 | MATLAB实现QRBiLSTM双向长短期记忆神经网络分位数回归多输入单输出区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 区间预测 | MATLAB实现QRBiLSTM…

uview中的常用的框

第一步&#xff1a; 先下载 uview UI 框架 详见 项目 引入 uView_vue引入uview_qq_2524963996的博客-CSDN博客【代码】 项目 引入 uView。_vue引入uviewhttps://blog.csdn.net/qq_44161703/article/details/131168976?spm1001.2014.3001.5501 第二步&#xff1a; 可以直接…

解锁潜力,驭数赋能:大数据与云计算的强强联合

随着数字化时代的来临&#xff0c;大数据和云计算已成为信息技术领域的两大热门话题。大数据指的是以海量、高速、多样化的数据为基础&#xff0c;通过分析和挖掘来获得有价值的信息和洞察。而云计算则是一种基于网络的计算模式&#xff0c;通过将数据和应用程序存储在云端服务…

【前端动画】科技感扫描效果 css动画animation

扫描出现动画 参考了网友写的二维码扫描 <template><div><div class"scan-content"><img style"width: 2rem;height: 2rem;" src"../../assets/images/eye.png" alt"" /><div class"line">…

Express 框架的基本操作

目录 1、应用生成器 2、基本路由 2.1、在跟路由下配置 GET请求&#xff0c;返回对应相应内容。 2.2、在跟路由下配置 POST请求&#xff0c;返回对应相应内容。 2.3、在跟路由下配置 PUT请求&#xff0c;返回对应相应内容。 2.4、在根路由下配置DELETE请求&#xff0c;返回对…

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询

目录 BACnet 使用软件 资源 模拟器 使用Java主动查 引入maven 创建网络对象 获取远程设备 获取设备属性 使用DeviceEventAdapter订阅 初始化本地BACnet设备和IP网络配置&#xff1a; 启动本地设备和添加监听器&#xff1a; 搜寻远程设备&#xff1a; 发送订阅COV报…

mybatis事物是如何和spring事物整合的

目录 1、mybatis事物管理器 2、SpringManagedTransactionFactory如何处理事物 3、spring事物如何设置connection连接到threadLocal 1、mybatis事物管理器 mybatis事物抽象接口类&#xff1a;Transaction。该接口定义了事物基本方法和获取数据库连接方法 该类有三个实现类Jd…

基于Java+SpringBoot+Vue前后端分离旅游网站详细设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

pytorch工具——使用pytorch构建一个分类器

目录 分类器任务和数据介绍训练分类器的步骤在GPU上训练模型 分类器任务和数据介绍 训练分类器的步骤 #1 import torch import torchvision import torchvision.transforms as transformstransformtransforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.…

docker数据网络管理

数据管理 管理 Docker 容器中数据主要有两种方式&#xff1a;数据卷&#xff08;Data Volumes&#xff09;和数据卷容器&#xff08;DataVolumes Containers&#xff09;。 1&#xff0e;数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机的目录挂…

详细解析python视频选择--【思维导图知识范围】

C ,JAVA JAVAWEB ,微信小程序等 都有视频选择的分析。 语言视频选择收录专辑链接C张雪峰推荐选择了计算机专业之后-在大学期间卷起来-【大学生活篇】JAVA黑马B站视频JAVA部分的知识范围、学习步骤详解JAVAWEB黑马B站视频JAVAWEB部分的知识范围、学习步骤详解SpringBootSpringB…

Qt/C++音视频开发48-推流到rtsp服务器

一、前言 之前已经打通了rtmp的推流&#xff0c;理论上按照同样的代码&#xff0c;只要将rtmp推流地址换成rtsp推流地址&#xff0c;然后格式将flv换成rtsp就行&#xff0c;无奈直接遇到协议不支持的错误提示&#xff0c;网上说要换成rtp&#xff0c;换了也没用&#xff0c;而…

斯坦福数据挖掘教程·第三版》读书笔记(英文版)Chapter 13 Neural Nets and Deep Learning

来源&#xff1a;《斯坦福数据挖掘教程第三版》对应的公开英文书和PPT Chapter 13 Neural Nets and Deep Learning In this chapter, we shall consider the design of neural nets, which are collections of perceptrons, or nodes, where the outputs of one rank (or lay…

使用 Docker 快速上手中文版 LLaMA2 开源大模型

本篇文章&#xff0c;我们聊聊如何使用 Docker 容器快速上手朋友团队出品的中文版 LLaMA2 开源大模型&#xff0c;国内第一个真正开源&#xff0c;可以运行、下载、私有部署&#xff0c;并且支持商业使用。 写在前面 感慨于昨天 Meta LLaMA2 模型开放下载之后&#xff0c;Git…

Spring Security 的工作原理/总体架构

目录 1、过滤器的视角 2、DelegatingFilterProxy 委派过滤器代理&#xff08;类&#xff09; 2、FilterChainProxy 过滤器链代理&#xff08;类&#xff09; 4、SecurityFilterChain 安全过滤器链&#xff08;接口&#xff09; 5、Security Filters 安全过滤器实例 6、Sp…

基于sklearn计算precision、recall等分类指标

文章目录 一、分类指标函数1.1 precision_score函数1.2 recall_score函数1.3 accuracy_score函数1.4 f1_score函数1.5 precision_recall_curve函数1.6 roc_curve函数1.7 roc_auc_score函数1.8 classification_report函数 二、二分类任务三、多分类任务3.1 Macro Average&#x…

Meta牵手Microsoft推出下一代Llama 2

官方消息 1、今天&#xff0c;我们将介绍 Llama 2 的可用性&#xff0c;这是我们的下一代开源大型语言模型。 2、Llama 2免费用于研究和商业用途。 3、Microsoft和 Meta 正在扩大他们的长期合作伙伴关系&#xff0c;Microsoft 是 Llama 2 的首选合作伙伴。 4、在技术、学术…

力扣 -- 122. 买卖股票的最佳时机 II

一、题目&#xff1a; 题目链接&#xff1a;122. 买卖股票的最佳时机 II - 力扣&#xff08;LeetCode&#xff09; 二、解题步骤 下面是用动态规划的思想解决这道题的过程&#xff0c;相信各位小伙伴都能看懂并且掌握这道经典的动规题目滴。 三、参考代码&#xff1a; clas…