大话设计模式——适配器模式

2023-11-07

适配器模式

适配器模式:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

系统的数据和行为都正确,但接口不符时,我们应该考虑用适配器,目的是使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。

这里我们学习的是对象适配器。
在这里插入图片描述

Target类

这是客户所期待的接口.目标可以是具体的或抽象的类,也可以是接口。

public abstract class Target {
    public void request() {
        System.out.println("普通请求");
    }
}

Adaptee(需要适配的类)

public class Adaptee {
    public void specificRequest() {
        System.out.println("特殊请求");
    }
}

Adapter

通过在内部包装一个Adaptee对象,把源接口转换成目标接口。
适配器实现目标接口,组装待适配对象。

public class Adapter extends Target {
    /**
     * 建立一个私有的Adaptee对象
     */
    private Adaptee adaptee = new Adaptee();
    
    @Override
    public void request() {
        // 这样就可以把表面上调用request方法变成实际上调用specificRequest方法
        adaptee.specificRequest();
    }
}

客户端

public class Client {
    public static void main(String[] args) {
        // 对客户端来说,调用的就是Target的request
        Target target = new Adapter();
        target.request();
    }
}

什么时候该使用适配器模式?

在想使用一个已经存在的类,如果它的接口要求的不相同时,就应该考虑使用适配器模式。两个类所做的事情相同或相似,但是具有不同的接口要使用它。

客户代码可以统一调用同一接口,这样更简单、更直接、更紧凑。

适配器模式有种“亡羊补牢”的感觉。

接口不相同时,首先不应该考虑用适配器,而是应该考虑通过重构统一接口。在双方都不太容易修改的时候再使用适配器模式适配,而不是一有不同时就使用它。

篮球翻译适配器案例

球员

//球员
public abstract class Player {
    protected String name;
    public Player(String name) {
        this.name = name;
    }
    //进攻
    public abstract void attack();
    // 防守
    public abstract void defense();
}

前锋、中锋、后卫

/**
 * 前锋
 */
public class Forwards extends Player{
    public Forwards(String name) {
        super(name);
    }
    @Override
    public void attack() {
        System.out.println(String.format("前锋 %s进攻", name));
    }
    @Override
    public void defense() {
        System.out.println(String.format("前锋 %s防守", name));
    }
}
/**
 * 中锋
 */
public class Center extends Player{
    public Center(String name) {
        super(name);
    }
    @Override
    public void attack() {
        System.out.println(String.format("中锋 %s进攻", name));
    }
    @Override
    public void defense() {
        System.out.println(String.format("中锋 %s防守", name));
    }
}
/**
 * 后卫
 */
public class Guards extends Player{
    public Guards(String name) {
        super(name);
    }
    @Override
    public void attack() {
        System.out.println(String.format("后卫 %s进攻", name));
    }
    @Override
    public void defense() {
        System.out.println(String.format("后卫 %s防守", name));
    }
}

客户端

public class Client {
    public static void main(String[] args) {
        Player forwards = new Forwards("巴蒂尔");
        forwards.attack();
        Player guards = new Guards("麦克格雷迪");
        guards.attack();
        Player center = new Center("姚明");
        center.attack();
        center.defense();
    }
}

在这里插入图片描述

外籍中锋

// 外籍中锋
public class ForeignCenter {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    // 外籍中锋的方法与中锋的方法不同
    public void myAttack() {
        System.out.println(String.format("外籍中锋 %s进攻", name));
    }

    // 外籍中锋的方法与中锋的方法不同
    public void myDefense() {
        System.out.println(String.format("外籍中锋 %s防守", name));
    }
}

翻译者

// 翻译者
public class Translator extends Player{

    /**
     * 声明并实例化一个内部“外籍中锋”对象,表名翻译者和外籍球员有关联
     */
    private ForeignCenter foreignCenter = new ForeignCenter();
    public Translator(String name) {
        super(name);
        foreignCenter.setName(name);
    }
    @Override
    public void attack() {
        // 翻译者将attach()->myAttack()
        foreignCenter.myAttack();
    }
    @Override
    public void defense() {
     // 翻译者将defense()->myDefense()
        foreignCenter.myDefense();
    }
}

客户端改写

public class Client {
    public static void main(String[] args) {
        Player forwards = new Forwards("巴蒂尔");
        forwards.attack();
        Player guards = new Guards("麦克格雷迪");
        guards.attack();
//        Player center = new Center("姚明");
//        center.attack();
//        center.defense();
        Player translator = new Translator("姚明");
        translator.attack();
        translator.defense();
        
    }
}

在这里插入图片描述
注:本文内容源自程杰的《大话设计模式》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

大话设计模式——适配器模式 的相关文章

  • 按下按钮并在java中的新窗口中打开文件

    我创建了一个 JFrame 并放置了一个文本字段和按钮 在文本字段中我放置了从文本文件读取的名称 我知道我想单击按钮并打开一个已知窗口 我想在其中放置名称 其他信息来自同一个文件 这是我的代码 这是我的主框架 package Fronten
  • TreeMap 删除所有大于某个键的键

    在项目中 我需要删除键值大于某个键的所有对象 键类型为Date 如果重要的话 据我所知TreeMapJava中实现的是红黑树 它是一种二叉搜索树 所以我应该得到O n 删除子树时 但除了制作尾部视图并一一删除之外 我找不到任何方法可以做到这
  • java.lang.ClassNotFoundException:javax.mail.MessagingException

    我想使用 eclipse 将电子邮件从我的 gmail 帐户发送到另一个邮件帐户 我使用 apache tomcat 7 0 34 作为我的 Web 服务器 并使用端口 8080 作为 apache 服务器 HTTP 1 1 并使用 JRE
  • 两个整数乘积的模

    我必须找到c c a b mod m a b c m 是 32 位整数 但 a b 可以超过 32 位 我正在尝试找出一种计算 c 的方法 而不使用 long 或任何 gt 32 位的数据类型 有任何想法吗 如果m是质数 事情可以简化吗 注
  • eclipse行号状态行贡献项是如何实现的?

    我需要更新状态行编辑器特定的信息 我已经有了自己的实现 但我想看看 eclipse 贡献项是如何实现的 它显示状态行中的行号 列位置 谁能指点一下 哪里可以找到源代码 提前致谢 亚历克斯 G 我一直在研究它 它非常复杂 我不确定我是否了解完
  • Java 的支持向量机?

    我想用Java编写一个 智能监视器 它可以随时发出警报detects即将到来的性能问题 我的 Java 应用程序正在以结构化格式将数据写入日志文件
  • Thymeleaf 3 Spring 5 映射加载字符串而不是 HTML

    我正在尝试将 Spring 5 和 Thymeleaf 3 一起配置 我正在 Eclipse 上工作 我使用 全新安装 构建并使用 springboot run 运行应用程序 我已经设置了一个控制器和几个模板 但 Thymeleaf 似乎找
  • 如何调试“com.android.okhttp”

    在android kitkat中 URLConnection的实现已经被OkHttp取代 如何调试呢 OkHttp 位于此目录中 external okhttp android main java com squareup okhttp 当
  • 将巨大的模式编译成Java

    有两个主要工具提供了将 XSD 模式编译为 Java 的方法 xmlbeans 和 JAXB 问题是 XSD 模式确实很大 30MB 的 XML 文件 大部分模式在我的项目中没有使用 所以我可以注释掉大部分代码 但这不是一个好的解决方案 目
  • 断言 Kafka 发送有效

    我正在使用 Spring Boot 编写一个应用程序 因此要写信给 Kafka 我这样做 Autowired private KafkaTemplate
  • Java继承,扩展类如何影响实际类

    我正在查看 Sun 认证学习指南 其中有一段描述了最终修饰符 它说 如果程序员可以自由地扩展我们所知的 String 类文明 它可能会崩溃 他什么意思 如果可以扩展 String 类 我是否不会有一个名为 MyString 的类继承所有 S
  • 如何将 HTML 链接放入电子邮件正文中?

    我有一个可以发送邮件的应用程序 用 Java 实现 我想在邮件中放置一个 HTML 链接 但该链接显示为普通字母 而不是 HTML 链接 我怎样才能将 HTML 链接放入字符串中 我需要特殊字符吗 太感谢了 Update 大家好你们好 感谢
  • 如何在JPanel中设置背景图片

    你好 我使用 JPanel 作为我的框架的容器 然后我真的想在我的面板中使用背景图片 我真的需要帮助 这是我到目前为止的代码 这是更新 请检查这里是我的代码 import java awt import javax swing import
  • 如何区分从 Saxon XPathSelector 返回的属性节点和元素节点

    给定 XML
  • 为什么\0在java中不同系统中打印不同的输出

    下面的代码在不同的系统中打印不同的输出 String s hello vsrd replace 0 System out println s 当我在我的系统中尝试时 Linux Ubuntu Netbeans 7 1 它打印 When I
  • 将 JavaFX FXML 对象分组在一起

    非常具有描述性和信息性的答案将从我这里获得价值 50 声望的赏金 我正在 JavaFX 中开发一个应用程序 对于视图 我使用 FXML
  • 部署 .war 时出现 Glassfish 服务器错误:部署期间发生错误:准备应用程序时出现异常:资源无效

    我正在使用以下内容 NetBeans IDE 7 3 内部版本 201306052037 爪哇 1 7 0 17 Java HotSpot TM 64 位服务器虚拟机 23 7 b01 NetBeans 集成 GlassFish Serve
  • 在 Spring 上下文中查找方法级自定义注释

    我想知道的是 所有的类 方法Spring http en wikipedia org wiki Spring Framework注释为 Versioned的bean 我创建了自定义注释 Target ElementType METHOD E
  • partitioningBy 必须生成一个包含 true 和 false 条目的映射吗?

    The 分区依据 https docs oracle com javase 8 docs api java util stream Collectors html partitioningBy java util function Pred
  • java'assert'和'if(){}else exit;'之间的区别

    java和java有什么区别assert and if else exit 我可以用吗if else exit代替assert 也许有点谷歌 您应该记住的主要事情是 if else 语句应该用于程序流程控制 而assert 关键字应该仅用于

随机推荐

  • 【Zabbix实战之部署篇】docker部署Zabbix+grafana监控平台

    Zabbix实战之部署篇 docker部署Zabbix grafana监控平台 一 Zabbix介绍 1 Zabbix简介 2 Zabbix的优点 3 Zabbix各组件介绍 4 Zabbix架构图 二 grafana介绍 1 grafan
  • plc梯形图100实例详解_干货

    今天给大家分享的是关于PLC编程控制入门常用到的实例 里面包含的知识点是较为齐全的 如 I O分配表 PLC接线图 梯形图程序等 一 电动机顺序启动 顺序停止控制 I O分配表 PLC接线图 梯形图程序 二 电动机的顺序启动 同时停止 I
  • windows家庭版本使用远程桌面

    windows家庭版是不支持远程桌面的 开源软件RDP Wrapper可以帮助家庭版也支持远程桌面的功能 Github项目地址 安装步骤 1 右键管理员运行install bat 2 右键管理员运行RDPConf exe 问题解决 1 se
  • 实体类监听器EntityListeners

    自定义实体类监听器类 public class DataBaseAuditListener PrePersist public void prePersist Object object throws IllegalArgumentExce
  • 两个栈实现一个队列(图解),一看就懂

    两个栈实现一个队列 要想实现此方法 我们现需要了解一下什么是栈和队列 栈 栈 Stack是一种只能在一端进行插入或删除操作的线性表 表中允许进行插入 删除操作的一端称为栈顶 Top 栈顶的当前位置是动态的 栈顶的当前位置是由一个称为栈顶指针
  • Windows+Ubuntu18.04双系统安装【完美版】

    经常卸载Ubuntu导致了卸载完后必须重装 我安装的Ubuntu版本是18 04 镜像下载链接Ubuntu 18 04 6 LTS Bionic Beaver 1 制作系统安装盘 1 1 安装并打开软碟通 插上 U 盘 并且最好备份你的 U
  • vue2 学习之路 常见的指令!

    文件夹 和 文件夹含义 主要的文件及其含义 node modules 下载的第三方包 安装目录 public index html 浏览器运行的网页 src main js webpack打包的入口文件 src App vue vue项目入
  • AndroidStudio设置代码自动提示以及字体大小设置

    我的Studio版本是3 14是按照我版本设置的 一 设置字体大小 File gt Settings gt Editor gt font gt size 如下图示 二 设置代码提示 File gt Settings gt General g
  • php对二维数组的某个值进行排序

    需求按type sum的大小来排序 array 5 0 gt string 1 1 1 gt string 1 2 2 gt string 1 2 3 gt string 1 2 4 gt string 1 3 最终结果 array 5 0
  • Error code of Media server (MediaPlayer内核异常码说明)

    Error code of Media server HRESULT Description 0x000D0000 The requested operation is pending completion 0 0x000D0001 The
  • Go_数据类型(值传递&引用传递)

    数据类型 计算机存储设备最小信息单位是位 bit 最小的存储单元是字节 byte 占用字节的不同 所表示能存储的数据长度不同 数据类型用来说明数据的数据的结构 便于定义变量 参数传递等 数据类型默认值 类型 默认值 整型 0 浮点型 0 0
  • SpringBoot后端接受前端传递对象参数

    SpringBoot后端接受前端传递对象参数 最近用到SpringBoot前端传递参数给后端踩得一些坑分享给大家 代码 类 Data public class ArticleVo JsonProperty value name privat
  • Burp Suite抓不到本地包/localhost包问题解决汇总

    一 火狐配置好IP和安装后BP的证书 1 首先在火狐浏览器中配置好本地IP选项 2 配置好后访问http burp 下载安装证书先点击右上角下载证书 3 下载好后双击运行 安装证书 二 尝试使用本地IP域名 我们将地址栏的localhost
  • 第四章. Pandas进阶—数据导出

    第四章 Pandas进阶 4 7 数据导出 1 导出 xlsx文件 1 语法 DataFrame to excel excel writer sheet name Sheet1 na rep float format None column
  • C#关于set()和get()方法的理解及使用

    set 与 get 意思 set是设置 get是获取 顾名思义 这两个方法是对数据进行设置和获取用的 C 面向对象编程中的封闭性和安全性 封闭性即对类中的域变量进行封闭操作 即用private来修饰他们 其他类则不能对该变量访问 这样我们就
  • PLC与旋转编码器的连接

    PLC与旋转编码器的连接 PLC与常用输入设备的连接 旋转编码器是一种光电式旋转测量装置 它将被测的角位移直接转换成数字信号 高速脉冲信号 因此可将旋转编码器的输出脉冲信号直接输入给PLC 利用PLC的高速计数器对其脉冲信号进行计数 以获得
  • Xshell4 注册码 ,Xftp4 注册码

    Xshell 4 注册码 690313 111999 999313 Xftp 4 注册码 101210 450789 147200 Xmanager注册码 101210 450789 147200 喜欢本文的朋友们 欢迎关注微信公众号 Ja
  • 一文读懂USB TypeC与USB-PD。TypeC引脚定义-24P 16P 6P,CC1、CC2的作用,USB-PD介绍,USB2.0/3.0接口类型一览

    USB TypeC USB PD USB接口类型 24P USB TypeC 引脚定义 USB TypeC 拥有诸多优点 双面可插不担心正反 可做USB 雷电高速传输载体 支持 PD快充 音频设备 HDMI传输 调试模式等诸多功能 市面上的
  • 【花雕学AI】超级提问模型大全!150个ChatGPT神奇示例,让你的聊天更有趣!

    引言 你是否想要成为聊天高手 让你的对话更加有趣和深入 你是否想要掌握一些超级提问模型 让你的聊天更加有创意和挑战 你是否想要借助人工智能的力量 生成一些适合你的超级提问模型 如果你的答案是肯定的 那么你一定不能错过这篇文章 在这里 我们将
  • 大话设计模式——适配器模式

    适配器模式 适配器模式 将一个类的接口转换成客户希望的另外一个接口 Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 系统的数据和行为都正确 但接口不符时 我们应该考虑用适配器 目的是使控制范围之外的一个原有对象与