深入浅出设计模式 - 适配器模式

这篇具有很好参考价值的文章主要介绍了深入浅出设计模式 - 适配器模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌

Java知识图谱点击链接:体系化学习Java(Java面试专题)

💕💕 感兴趣的同学可以收藏关注下不然下次找不到哟💕💕

深入浅出设计模式 - 适配器模式

1、什么是适配器模式

适配器模式是一种结构型设计模式,它用于将一个类的接口转换成客户端所期望的另一个接口。适配器模式可以让原本由于接口不兼容而无法一起工作的类能够协同工作。

适配器模式的主要作用是解决两个已有接口之间的不兼容问题,以便它们能够协同工作。适配器模式有三种实现方式:类适配器、对象适配器和接口适配器。

类适配器是通过继承来实现的,它可以适配一个类的接口到另一个类的接口。对象适配器是通过组合来实现的,它可以适配一个对象的接口到另一个对象的接口。接口适配器是通过抽象类来实现的,它可以适配一个接口的部分方法到另一个接口。

适配器模式的优点是可以让原本不兼容的接口协同工作,提高代码的复用性和灵活性。缺点是可能会增加代码的复杂度和维护成本。

2、适配器模式的优缺点

适配器模式的优点:

  1. 可以让原本不兼容的接口协同工作,提高代码的复用性和灵活性。

  2. 可以将适配器类和目标类解耦,使得适配器类和目标类可以独立变化。

  3. 可以增加代码的可读性和可维护性,使代码更加清晰。

适配器模式的缺点:

  1. 可能会增加代码的复杂度和维护成本。

  2. 适配器模式需要增加一个额外的适配器类,增加了代码的量。

  3. 如果设计不当,可能会导致适配器类的滥用,增加代码的混乱程度。

3、适配器模式的应用场景

适配器模式的应用场景:

  1. 旧接口适配新接口:当系统中的一个类需要使用另一个类的接口,但是这两个类的接口不兼容时,可以使用适配器模式。适配器模式可以将一个类的接口转换成系统需要的另一个接口,从而使得原本不兼容的类可以协同工作。

  2. 多个类的接口统一:当系统中的多个类的接口不统一时,可以使用适配器模式将它们的接口统一成一个接口。这样,这些类就可以协同工作,提高了系统的灵活性和可扩展性。

  3. 适配器模式还可以用于封装有缺陷的接口设计。如果接口的设计不完善,或者需要进行修改,但是又不能对客户端代码产生影响,可以使用适配器模式来封装这些缺陷接口,从而提供一个稳定的接口给客户端使用。

4、适配器模式的结构

适配器模式的结构包括以下几个角色:

  1. 目标接口(Target):定义客户端使用的接口,也就是客户端期望的接口。

  2. 源接口(Adaptee):定义需要适配的接口,也就是客户端现有的接口。

  3. 适配器(Adapter):实现目标接口,并持有一个源接口的引用,用于将客户端的请求转换成对源接口的调用。

  4. 客户端(Client):使用目标接口来调用适配器的方法,从而间接调用源接口的方法。

在适配器模式中,客户端通过调用目标接口来使用适配器的方法。适配器持有一个源接口的引用,用于将客户端的请求转换成对源接口的调用,并将返回结果转换成客户端期望的格式。这样,客户端就可以使用适配器来调用源接口的方法,而不需要了解源接口的实现细节。

5、类适配器模式的代码案例

以下是一个使用类适配器模式的示例代码:

假设我们有一个 Adaptee 类,它具有一个 specificRequest() 方法,但是它的接口与我们需要的 Target 接口不兼容。我们需要一个适配器来使得 Adaptee 类能够适配 Target 接口。

首先,我们定义一个 Target 接口:

package com.pany.camp.design.principle.adapter.clazz;

/**
 *
 * @description:  
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 16:57 
 */
public interface Target {
    void request();
}

然后,我们定义一个 Adaptee 类:

package com.pany.camp.design.principle.adapter.clazz;

/**
 *
 * @description:  Adaptee
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 16:58
 */
public class Adaptee {

    public void specificRequest() {
        System.out.println("Adaptee specific request");
    }
}

接下来,我们创建一个适配器类 Adapter ,它继承了 Adaptee 类,并实现了 Target 接口:

package com.pany.camp.design.principle.adapter.clazz;

/**
 *
 * @description:  适配器类
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 16:59 
 */
public class Adapter extends Adaptee implements Target {
    @Override
    public void request() {
        specificRequest();
    }
}

在适配器类中,我们继承了 Adaptee 类,并实现了 Target 接口。在 request() 方法中,我们调用了 specificRequest() 方法,从而使得 Adaptee 类能够适配 Target 接口。

最后,我们可以使用适配器来调用 Target 接口的方法:

package com.pany.camp.design.principle.adapter.clazz;

/**
 *
 * @description:  客户端
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 17:00
 */
public class Client {
    public static void main(String[] args) {
        Target target = new Adapter();
        target.request();
    }
}

输出结果如下:

Adaptee specific request

Process finished with exit code 0

在客户端代码中,我们创建了一个适配器对象,并将其赋值给 Target 接口的引用。然后,我们调用了 request() 方法,实际上是调用了适配器的 request() 方法,从而间接调用了 Adaptee 类的 specificRequest() 方法。

6、对象适配器模式的代码案例

以下是一个使用对象适配器模式的示例代码:

假设我们有一个 Adaptee 类,它具有一个 specificRequest() 方法,但是它的接口与我们需要的 Target 接口不兼容。我们需要一个适配器来使得 Adaptee 类能够适配 Target 接口。

首先,我们定义一个 Target 接口:

package com.pany.camp.design.principle.adapter.object;

/**
 *
 * @description:  Target
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 17:03
 */
public interface Target {
    void request();
}

然后,我们定义一个 Adaptee 类:

package com.pany.camp.design.principle.adapter.object;

/**
 *
 * @description:  Adaptee
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 17:04
 */
public class Adaptee {
    
    public void specificRequest() {
        System.out.println("Adaptee specific request");
    }
}

接下来,我们创建一个适配器类 Adapter ,它实现了 Target 接口,并持有一个 Adaptee 对象的引用:

package com.pany.camp.design.principle.adapter.object;

/**
 *
 * @description:  适配器类
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 17:04
 */
public class Adapter implements Target {
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

在适配器类中,我们实现了 Target 接口,并持有一个 Adaptee 对象的引用。在 request() 方法中,我们调用了 Adaptee 对象的 specificRequest() 方法,从而使得 Adaptee 类能够适配 Target 接口。

最后,我们可以使用适配器来调用 Target 接口的方法:

package com.pany.camp.design.principle.adapter.object;

/**
 *
 * @description:  客户端类
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 17:05
 */
public class Client {

    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        Target target = new Adapter(adaptee);
        target.request();
    }
}

在客户端代码中,我们创建了一个 Adaptee 对象和一个适配器对象,并将适配器对象赋值给 Target 接口的引用。然后,我们调用了 request() 方法,实际上是调用了适配器的 request() 方法,从而间接调用了 Adaptee 类的 specificRequest() 方法。

7、接口适配器模式的代码案例

以下是一个简单的接口适配器模式的代码案例,使用Java语言实现:

  1. 定义目标接口
package com.pany.camp.design.principle.adapter.interfaces;

/**
 *
 * @description:  Target
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 17:16
 */
public interface Target {
    void request();
}
  1. 实现目标接口的具体类
package com.pany.camp.design.principle.adapter.interfaces;

/**
 *
 * @description:  具体类
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 17:16
 */
public class ConcreteTarget implements Target {
    @Override
    public void request() {
        System.out.println("ConcreteTarget.request() is called");
    }
}
  1. 定义适配器接口
package com.pany.camp.design.principle.adapter.interfaces;

/**
 *
 * @description:  适配器接口
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 17:17
 */
public interface Adapter {
    void specificRequest();
}
  1. 实现适配器接口的具体类,同时持有目标接口的引用
package com.pany.camp.design.principle.adapter.interfaces;

/**
 *
 * @description:  适配器接口的具体类
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 17:17
 */
public class ConcreteAdapter implements Adapter {

    private Target target;

    public ConcreteAdapter(Target target) {
        this.target = target;
    }

    @Override
    public void specificRequest() {
        System.out.println("ConcreteAdapter.specificRequest() is called");
        target.request();
    }
}
  1. 在客户端中使用适配器
package com.pany.camp.design.principle.adapter.interfaces;

/**
 *
 * @description:  客户端
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 17:20
 */
public class Client {
    public static void main(String[] args) {
        Target target = new ConcreteTarget();
        Adapter adapter = new ConcreteAdapter(target);
        adapter.specificRequest();
    }
}

在上面的代码中, ConcreteTarget 是目标接口的具体实现类, ConcreteAdapter 是适配器接口的具体实现类,并且持有一个目标接口的引用。在客户端中,我们创建了一个目标接口的实例和一个适配器接口的实例,然后通过适配器接口调用目标接口的方法。

深入浅出设计模式 - 适配器模式

💕💕 本文由激流原创,首发于CSDN博客,博客主页 https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421
💕💕喜欢的话记得点赞收藏啊文章来源地址https://www.toymoban.com/news/detail-504053.html

到了这里,关于深入浅出设计模式 - 适配器模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《深入浅出.NET框架设计与实现》笔记1——.NET CLI 概述

    .NET CLI(NET 命令行接口)工具是用于开发生成运行和发布.NET应用程序的跨平台工具链。 默认安装的命令有 1、基本命令 2、项目修改命令 3、高级命令 4、工具管理命令 工具三控制台应用程序,它们从NuGet包中安装并从命令提示符处进行调用。 CLI命令结构包 含驱动程序(“

    2024年04月22日
    浏览(39)
  • 【动手学深度学习】深入浅出深度学习之RMSProp算法的设计与实现

    目录 🌞一、实验目的 🌞二、实验准备 🌞三、实验内容 🌼1. 认识RMSProp算法 🌼2. 在optimizer_compare_naive.py中加入RMSProp 🌼3. 在optimizer_compare_mnist.py中加入RMSProp 🌼4. 问题的解决 🌞四、实验心得 深入学习RMSProp算法的原理和工作机制; 根据RMSProp算法的原理,设计并实现一个

    2024年04月10日
    浏览(37)
  • 【设计模式】使用适配器模式做补偿设计

    适配器模式是一种 结构型设计模式 ,它提供了一个中间层,通过这个中间层,客户端可以使用统一的接口与具有不同接口的类进行交互,也就是说,将一个接口转换成客户期望的另一个接口,使得原本不兼容的接口能够协同工作。 举个现实中的例子,我们现在的很多轻薄笔

    2024年02月22日
    浏览(35)
  • 设计模式--适配器模式

    目录 基本介绍 工作原理 类适配模式 介绍 应用实例介绍 类适配器模式注意事项和细节 对象适配模式 介绍 对象适配器模式注意事项和细节 接口适配器模式 介绍 适配器模式的注意事项和细节  (1) 适配器模式(Adapter Pattern) 将某个类的接口转换成客户端期望的另一个接口表示

    2023年04月26日
    浏览(34)
  • 【设计模式】适配器模式

    适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。 这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。

    2024年02月12日
    浏览(51)
  • 设计模式-适配器模式

    在我们生活中,插座输出的电源都是220V的,而我们手机充电需要的电压基本都是5V的。我们不能直接用220V的电压来给手机充电,也不能说专门有线路来提供5V的电压。所以就有了充电器,充电器可以将220V的电压转为5V的电压,这样我们就方便太多了。 上面所说的充电器其实就

    2024年02月08日
    浏览(38)
  • 设计模式——适配器模式

    说起适配器其实在我们的生活中是非常常见的,比如:学校的宿舍的电压都比较低,而有的学生想使用大功率电器,宿舍的就会跳闸,然而如果你使用一个适配器(变压器)就可以使用了(温馨提示宿舍使用大功率电器不太安全,容易引起火灾,希望大家谨慎使用)。 又比如

    2024年02月12日
    浏览(47)
  • 《设计模式》之适配器模式

    把一个类的接口转换成客户端所期待的另一种接口,从而使原接口不匹配而无法再一起工作的两个类能在一起工作。 在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不能满足的。 如何应对

    2024年02月09日
    浏览(42)
  • 设计模式 06 适配器模式

    适配器模式(Adapter Pattern)属于 结构型 模式 结构型 模式关注如何将现有的类或对象组织在一起形成更加强大的结构。 在生活中,我们经常遇到这样的一个问题:轻薄笔记本通常只有 type-c 或者 usb-a 接口,没有网口。但日常使用中是往往需要连接网口上网的,这时想到的第

    2024年02月11日
    浏览(31)
  • 设计模式四:适配器模式

    1、适配器模式的理解 适配器模式可以理解为有两个现成的类Adaptee和Target,它们两个是不能动的,要求必须使用B这个类来实现一个功能,但是A的内容是能复用的,这个时候我们需要编写一个转换器 适配器模式 Adaptee:被适配者,现有的接口或者类; Adapter:适配器类,适配器

    2024年02月22日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包