Java 23种设计模式(6.结构型模式-适配器模式)

news2025/2/27 0:39:56

结构型模式-适配器模式

代码分析

类图

在这里插入图片描述

代码

public class Target {//就是客户期待的接口,目标可以是具体,抽象的类,也可以是接口
    public String Request(){
        String  msg= "normal request";
        return msg;
    }
}

public class Adaptee {
    public String SpecificRequest(){
        String  msg= "special request";
        return msg;
    }
}

public class Adapter extends Target{//通过内部包装一个Adaptee对象,把原接口转为目标接口
    private Adaptee adaptee = new Adaptee();//新建一个私有的Adaptte对象

    public void Request(Adaptee adaptee){//表面上调用的Request()方法变为实际调用的SpecificRequest()
        adaptee.SpecificRequest();
    }
}

public class Client {
    public static void main(String[] args) {
        Target target = new Adapter();//对客户端而言,调用的就是Target的Request()
        System.out.println(target.Request());
    }
}

运行结果

normal request

1.概述

如果去欧洲国家去旅游的话,他们的插座如下图最左边,是欧洲标准。而我们使用的插头如下图最右边的。因此我们的笔记本电脑,手机在当地不能直接充电。所以就需要一个插座转换器,转换器第1面插入当地的插座,第2面供我们充电,这样使得我们的插头在当地能使用。生活中这样的例子很多,手机充电器(将220v转换为5v的电压),读卡器等,其实就是使用到了适配器模式。
在这里插入图片描述
定义:
将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
适配器模式分为类适配器模式对象适配器模式,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。

2.结构

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

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

3. 类适配器模式

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

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

实现-类图

在这里插入图片描述

代码

public interface SDCard {
    public String readSD();
    public void writeSD(String msg);
}
public class SDCardImpl implements SDCard{
    @Override
    public String readSD() {
        System.out.println("Using readSD to read ");
        String msg= "Using readSD to read msg:java";
        return msg;
    }
    @Override
    public void writeSD(String msg) {
        System.out.println("Using writeSD to write msg");
        System.out.println("Using writeSD to write msg:"+msg);
    }
}
public class Computer {
    public String readSD(SDCard sdCard){
        if(sdCard ==null){
            throw new NullPointerException("sd card null");
        }
        return sdCard.readSD();
    }
}
public interface TFCard {
    public String readTF();
    public void writeTF(String msg);
}
public class TFCardImpl implements TFCard{
    @Override
    public String readTF() {
        String msg ="Using readTF to read msg:python";
        return msg;
    }

    @Override
    public void writeTF(String msg) {
        System.out.println("Using writeTF to write msg" +msg);
    }
}

public class SDAdapterTF  extends TFCardImpl implements SDCard{

    public String readSD(){
        System.out.println("Using SDAdapterTF to read");
        return readTF();
    }
    public void writeSD(String msg){
        System.out.println("Using SDAdapterTF to write");
        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 sdAdapterTF = new SDAdapterTF(tfCard);
        System.out.println(computer.readSD(sdAdapterTF));
    }
}

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

运行结果

Using readSD to read 
Using readSD to read msg:java
--------
Using SDAdapterTF to read
Using readTF to read msg:python

4.对象适配器模式

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

实现-类图

在这里插入图片描述

代码

public interface SDCard {
    public String readSD();
    public void writeSD(String msg);
}
public class SDCardImpl implements SDCard{
    @Override
    public String readSD() {
        System.out.println("Using readSD to read ");
        String msg= "Using readSD to read msg:java";
        return msg;
    }
    @Override
    public void writeSD(String msg) {
        System.out.println("Using writeSD to write msg");
        System.out.println("Using writeSD to write msg:"+msg);
    }
}
public class Computer {
    public String readSD(SDCard sdCard){
        if(sdCard ==null){
            throw new NullPointerException("sd card null");
        }
        return sdCard.readSD();
    }
}
public interface TFCard {
    public String readTF();
    public void writeTF(String msg);
}
public class TFCardImpl implements TFCard{
    @Override
    public String readTF() {
        String msg ="Using readTF to read msg:python";
        return msg;
    }

    @Override
    public void writeTF(String msg) {
        System.out.println("Using writeTF to write msg" +msg);
    }
}

package com.Amy.model.adapter;

/**
 * @author: Amy
 * @create: 2023-01-24 15:08
 **/
public class SDAdapterTF implements SDCard{
//public class SDAdapterTF  extends TFCardImpl implements SDCard
//    public String readSD(){
//        System.out.println("Using SDAdapterTF to read");
//        return readTF();
//    }
//    public void writeSD(String msg){
//        System.out.println("Using SDAdapterTF to write");
//        writeTF(msg);
//    }
    private TFCard tfCard; //声明成员变量
    public SDAdapterTF(TFCard tfCard){//添加构造方法
        this.tfCard = tfCard;
    }
    public String readSD(){
        System.out.println("Using SDAdapterTF to read");
        return tfCard.readTF();
    }
    public void writeSD(String msg){
        System.out.println("Using SDAdapterTF to write");
        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 sdAdapterTF = new SDAdapterTF(tfCard);//构造方法实现
        System.out.println(computer.readSD(sdAdapterTF));
    }
}

运行结果

Using readSD to read 
Using readSD to read msg:java
--------
Using SDAdapterTF to read
Using readTF to read msg:python

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

5. 应用场景

  • 以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致。
  • 使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同

6.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的设计实现在实际上采用了适配器模式。

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

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

相关文章

零基础学JavaWeb开发(二十五)之 vue快速入门

一、什么是VUE Vue 是一套用于构建用户界面的渐进式JavaScript框架,简化dom操作。 基于MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel …

【头歌】循环单链表的基本操作

循环单链表的基本操作第1关:循环单链表的插入操作任务描述本关任务:编写循环单链表的插入操作函数。相关知识对于单链表,每个结点只存储了其后继结点的地址。尾结点之后不再有任何结点,那么它的next域设置有两种方式:将…

Python爬虫网页解析神器Xpath详细讲解

1、XPath介绍 XPath 是一门在 XML 文档中查找信息的语言。最初是用来搜寻 XML 文档的,但同样适用于 HTML 文档的搜索。 2、安装lxml lxml是Python的第三方解析库,支持HTML和XML解析,而且效率极高,弥补了Python自带的xml标准库在…

Mybatis-Plus id生成策略控制

目录 id生成策略控制 不同的表应用不同的id生成策略 名称 TableId AUTO策略 除了AUTO这个策略以外,还有如下几种生成策略: 分布式ID是什么? INPUT策略 ASSIGN_ID策略 ASSIGN_UUID策略 雪花算法 ID生成策略对比 id生成策略控制 不同的表应用不同的id生成…

计算机组成原理 | 第六章:计算机的运算方法 | 进制转换 | 定点运算 | 浮点数运算

文章目录📚进位计数制🐇任意进制转十进制🐇十进制整数转换为n进制整数🐇十进制小数转换为n进制小数🐇二/八/十六进制的互换📚带符号的二进制数表示⭐️🐇原码表示法🐇补码表示法&…

“买卖股票的最佳时机” 系列——我来教你稳赚不亏~

目录 前言 一、买卖股票的最佳时机 ——>指定次数交易(1次) 1.1、dp定义 1.2、递推公式 1.3、遍历顺序 1.4、初始化 1.5、解题代码 二、买卖股票的最佳时机II ——>交易到结束 2.1、分析 2.2、解题代码 三、买股票的最佳时机III ——>…

【keepass】密码管理软件keepass的安全风险分析,如何在使用keepass的过程中避免泄露数据库信息和密码?

一、安全风险分析 1.1 不正规的来源 如果你使用非官方渠道获得keepass软件或某些插件,那么你的密码管理从一开始就没有安全性可言。因为这玩意是开源的啊,如果对方“很懂”,只要往里面植入一些代码,让你的数据库文件和密钥在后台…

react 项目 中 使用 Dllplugin 打包优化

webpack在build包的时候,有时候会遇到打包时间很长的问题,这里提供了一个解决方案,让打包如丝般顺滑~ 在用 Webpack 打包的时候,对于一些不经常更新的第三方库,比如 react,lodash,vue 我们希望…

C语言基础知识(37)

数组一维数组的定义:类型说明符 数组名【常量表达式】;先定义后引用;一维数组初始化时可以只对一部分元素初始化,在对全部数组元素初始化的时候可以部规定长度;但是若被定义的数组长度与提供的初始值不一样时&#xff…

【MySQL】MySQL索引夺命连环问「持续更新中」

文章目录1. 使用MySQL索引的原因2. 索引的三种常见底层数据结构以及优缺点3. 索引的常见类型以及它是如何发挥作用的?4. MyISAM 和 InnoDB 实现 B 树索引方式的区别是什么?5. InnoDB 为什么设计 B 树索引?6. 什么是覆盖索引和索引下推&#x…

【JavaSE专栏7】Java 常量、变量及其作用域

作者主页:Designer 小郑 作者简介:Java全栈软件工程师一枚,来自浙江宁波,负责开发管理公司OA项目,专注软件前后端开发(Vue、SpringBoot和微信小程序)、系统定制、远程技术指导。CSDN学院、蓝桥云…

Python论文绘图利器seaborn.lineplot

Python论文绘图利器seaborn.lineplot 提示:前言 Python论文绘图利器seaborn.lineplot 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录Python论文绘图利器seaborn.lineplot前言一、导入包二、加载数据三…

嵌入式桌面管理系统Matchbox

简介 Matchbox(中文译名;火柴盒)是X Window System的免费和开源Window Manager,它主要用于嵌入式系统。取名Matchbox,很形象的表明它只适用于屏幕只有火柴盒大小的设备。 buildroot 移植MatchBox session managermat…

高斯秩变换 RankGauss 可能是比标准化/归一化更有效的连续值特征变换方法

文章目录 一、前言二、关键原理三、总结CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、前言 高斯秩变换是 Kaggle 竞赛大佬 Michael Jahrer(Grandmaster) 提出的一种新颖的特征变换方法,他称之为 RankGauss。类似归一化(MinMax)和标准化(Standardization)的作用,…

帆软报表 V8 get_geo_json 任意文件读取漏洞

帆软报表 V8 get_geo_json 任意文件读取漏洞 CNVD-2018-04757 1.漏洞介绍 FineReport报表软件是一款纯Java编写的,集数据展示(报表)和数据录入(表单)功能于一身的企业级web报表工具。 FineReport v8.0版本存在任意文件读取漏洞,攻击者可利用漏洞读取网…

车载以太网 - 测试用例设计 - 头部信息检测 - 10

前面的篇幅已经把ISO 13400中DoIP软件协议规范部分进行详细的介绍说明,如果在文章中有哪些介绍的不充分或者不够详细,欢迎评论区留言讨论;接下来的文章主要介绍DoIP协议相关的测试用例设计,这也是一个测试工程师必备的重要技能之一,能否保证测试执行完成后,软件质量是达到…

超级详解洛谷P4011 孤岛营救问题(bfs超难题)(保证看懂)

题目 说明 1944 年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩。瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到了迷宫的地形图。迷宫的外形是一个长方形&#xff…

阿里“云开发“小程序(uniCould)

博主ps: 网上资料少的可怜,哎,腾讯云涨价了,论服务器,我肯定选的阿里,再着你们对比下unicould的报价就知道了,如果有钱就另当别论了。 所以这片博文,博主试过之后,先抛出…

(day8) 自学Java——拼图小游戏

GUI(图形用户接口),是指采用图形化的方式显示操作界面。 Java中包含两套完整体系:AWT包,Swing包 一.代码 package com.abc.ui;import javax.swing.*; import javax.swing.border.BevelBorder; import java.awt.event.ActionEvent; import ja…

JavaEE day5 初识CSS 2

选择器 基本选择器:id选择器、类选择器、元素选择器 复合选择器:并列选择器、子孙选择器、孩子选择器 通配符选择器 *{.....} 任意元素:书写一些全局的规则时使用,就等于是一个全局都要遵守的规则 伪类选择器:针…