适配器模式:如何让不兼容的接口变得兼容

适配器,模式,如何,兼容,接口,变得 · 浏览次数 : 213

小编点评

**适配器模式** **简介** 适配器模式是一种结构型设计模式,通过一个适配器来将一个接口转换成另一个接口,从而使原本由于接口不兼容而不能一起工作的类可以一起工作。 **优点** * 增强程序的可扩展性 * 提高类的复用性 * 增加类的透明度 * 灵活地切换不同的被适配者 **缺点** * 增加了系统的复杂性 * 可能降低系统的性能 **应用场景** * 当需要在一个已有系统中引入新的功能或接口时,它与系统的目标接口不兼容,但又不能修改原有代码时 * 在多个独立开发的系统或者组件之间进行协作时,由于各自采用了不同的接口或者协议时 **代码示例** ```java // 目标接口 TriplePin public interface TriplePin { void electrify(int l, int n, int e); } // 被适配者接口 DualPin public interface DualPin { void electrify(int l, int n); } //适配器类 TriplePinAdapter public class TriplePinAdapter implements TriplePin { private DualPin dualPin; public TriplePinAdapter(DualPin dualPin) { this.dualPin = dualPin; } @Override public void electrify(int l, int n, int e) { // 调用被适配设备的两插通电方法,忽略地线参数e dualPin.electrify(l, n); } } // 客户端类 public class Client { public static void main(String[] args) { // 创建三相接口的适配器 TriplePinAdapter triplePinAdapter = new TriplePinAdapter(new TV()); // 使用适配器将 TV 类与三项接口兼容 triplePinAdapter.electrify(1, 0, -1); } } ``` **总结** 适配器模式是一种方便的解决方案,可以使原本由于接口不兼容而不能一起工作的类可以一起工作。但是,它也增加了系统的复杂性,可能降低系统的性能。

正文

在软件开发中,我们经常会遇到这样的情况:我们需要使用一个现有的类或者接口,但它与我们系统的目标接口不兼容,而我们又不能修改它。这时候,我们该怎么办呢?大多数情况下我们都可以使用适配器模式来解决这个问题,本文将从以下四个方面讲解适配器模式

  • 简介
  • 优缺点
  • 应用场景
  • Java 代码示例

简介

适配器模式(Adapter Pattern)是一种结构型设计模式,它可以将一个接口转换成客户端所期待的另一个接口,从而使原本由于接口不兼容而不能一起工作的类可以一起工作。适配器模式也称为包装器模式(Wrapper Pattern),因为它通过一个包装类(即适配器)来包装不兼容的接口,并提供统一的目标接口。适配器模式可以在运行时根据需要选择不同的适配器来适配不同的被适配者。

对象适配器模式的各角色定义如下。

  • Target(目标接口):客户端要使用的目标接口标准,对应下文中的三相插孔接口 TriplePin。
  • Adapter(适配器):实现了目标接口,负责适配(转换)被适配者的接口 specificRequest()为目标接口 request(),对应本章下文中的电视机专属适配器类 TriplePinAdapter。
  • Adaptee(被适配者):被适配者的接口标准,目前不能兼容目标接口的问题接口,可以有多种实现类,对应下文中的两相插孔接口 DualPin。
  • Client(客户端):目标接口的使用者。

推荐博主开源的 H5 商城项目waynboot-mall,这是一套全部开源的微商城项目,包含三个项目:运营后台、H5 商城前台和服务端接口。实现了商城所需的首页展示、商品分类、商品详情、商品 sku、分词搜索、购物车、结算下单、支付宝/微信支付、收单评论以及完善的后台管理等一系列功能。 技术上基于最新得 Springboot3.0、jdk17,整合了 MySql、Redis、RabbitMQ、ElasticSearch 等常用中间件。分模块设计、简洁易维护,欢迎大家点个 star、关注博主。

github 地址:https://github.com/wayn111/waynboot-mall

优缺点

适配器模式的优点有:

  • 适配器模式可以增强程序的可扩展性,通过使用适配器,可以在不修改原有代码的基础上引入新的功能或者接口。
  • 适配器模式可以提高类的复用性,通过使用适配器,可以将已有的类或者接口重新组合和封装,使其符合新的需求。
  • 适配器模式可以增加类的透明度,通过使用适配器,客户端只需要关注目标接口,而无需了解被适配者的具体实现。
  • 适配器模式可以灵活地切换不同的被适配者,通过使用不同的适配器,可以动态地选择不同的被适配者来满足不同的场景。

适配器模式的缺点有:

  • 适配器模式会增加系统的复杂性,过多地使用适配器会使系统变得零乱和难以理解。
  • 适配器模式可能会降低系统的性能,因为每次调用目标接口时都需要经过适配器的转换。
  • 适配器模式可能会违反开闭原则,如果目标接口发生变化,则需要修改所有的适配器类。

应用场景

适配器模式适用于以下场景:

  • 当需要在一个已有系统中引入新的功能或者接口时,它与系统的目标接口不兼容,但又不能修改原有代码时,可以使用适配器模式。例如在一个数据库操作系统中,如果想要支持多种类型的数据库源,但系统只提供了一个固定类型数据库源的操作接口时,可以使用一个数据库源操作适配器来将不同类型数据库源转换成统一类型数据库源。
  • 当需要在多个独立开发的系统或者组件之间进行协作时,但由于各自采用了不同的接口或者协议时,可以使用适配器模式。例如在一个分布式服务系统中,如果想要让不同语言编写的服务之间进行通信和调用,但各自采用了不同的通信协议和数据格式时,可以使用一个服务通信适配器来将不同协议和数据格式转换成统一协议和数据格式。

Java 代码示例

举一个生活中常见的实例,我们新买了一台电视机,其电源插头是两相的,不巧的是墙上的插孔却是三相的,这时电视机便无法通电使用,我们以代码来重现这个场景。

  1. 定义目标接口:三相插口 TriplePin,其中 3 个参数 l、n、e 分别对应火线(live)、零线(null)和地线(earth)。
public interface TriplePin {

    public void electrify(int l, int n, int e);
}
  1. 定义被适配者接口:两项插口 DualPin,可以看到参数中缺少了地线 e 参数。
public interface DualPin {

    public void electrify(int l, int n);
}

  1. 添加被适配者接口具体实现类:TV,可以看到 TV 实现的是两相接口,所在无法直接在三项接口中使用。
public class TV implements DualPin {
    @Override
    public void electrify(int l, int n) {
        System.out.println("火线通电:" + l + ",零线通电:" + n);
        System.out.println("电视开机");
    }
}

  1. 定义适配器类:三项接口适配器 TriplePinAdapter,实现了三项接口并且包含两项接口属性,在 electrify 方法中调用被适配设备的两插通电方法,忽略地线参数 e,以此来完成三项接口对两项接口的兼容。

这也就意味着 TriplePinAdapter 类能帮助我们将 TV 类与三项接口兼容。

public class TriplePinAdapter implements TriplePin {

    private DualPin dualPin;

    public TriplePinAdapter(DualPin dualPin) {
        this.dualPin = dualPin;
    }

    @Override
    public void electrify(int l, int n, int e) {
        // 调用被适配设备的两插通电方法,忽略地线参数e
        dualPin.electrify(l, n);
    }
}
  1. 定义客户端类
public class Client {

    public static void main(String[] args) {
        DualPin dualPinDevice = new TV();
        TriplePin triplePinDevice = new TriplePinAdapter(dualPinDevice);
        triplePinDevice.electrify(1, 0, -1);
    }
}

输出结果如下:

火线通电:1,零线通电:0
电视开机

总结

通过利用适配器模式对系统进行扩展后,我们就不必再为解决兼容性问题去暴力修改类接口了,转而通过适配器,以更为优雅、巧妙的方式将两侧“对立”的接口“整合”在一起,顺利化解双方难以调和的矛盾,最终使它们顺利接通。

关注公众号【waynblog】每周分享技术干货、开源项目、实战经验、国外优质文章翻译等,您的关注将是我的更新动力!

与适配器模式:如何让不兼容的接口变得兼容相似的内容:

适配器模式:如何让不兼容的接口变得兼容

在软件开发中,我们经常会遇到这样的情况:我们需要使用一个现有的类或者接口,但它与我们系统的目标接口不兼容,而我们又不能修改它。这时候,我们该怎么办呢?大多数情况下我们都可以使用适配器模式来解决这个问题,**本文将从以下四个方面讲解适配器模式**。 - 简介 - 优缺点 - 应用场景 - Java 代

Android 架构模式如何选择

Android架构模式飞速演进,目前已经有MVC、MVP、MVVM、MVI。到底哪一个才是自己业务场景最需要的,不深入理解的话是无法进行选择的。这篇文章就针对这些架构模式逐一解读。重点会介绍Compose为什么要结合MVI进行使用。希望知其然,然后找到适合自己业务的架构模式。

事实胜于雄辩,苹果MacOs能不能玩儿机器/深度(ml/dl)学习(Python3.10/Tensorflow2)

坊间有传MacOs系统不适合机器(ml)学习和深度(dl)学习,这是板上钉钉的刻板印象,就好像有人说女生不适合编程一样的离谱。现而今,无论是Pytorch框架的MPS模式,还是最新的Tensorflow2框架,都已经可以在M1/M2芯片的Mac系统中毫无桎梏地使用GPU显卡设备,本次我们来分享如何在

从热爱到深耕,全国Top10开源软件出品人手把手教你如何做开源

摘要:DTT直播邀请到管雷鸣与广大开发者分享“如何在开源领域找到适合自己的路”。 “想象一下,你写的代码被越来越多的人使用,并极大地帮助他们提高了开发效率和稳定性。”这是不是一件很酷的事?而这正是开源的魅力… 开源作为一种推动软件开发技术创新的新模式,广受开发者的喜爱。作为拥有40余个开源项目,全国

【23种设计模式】适配器模式(六)

## 前言 从今天开始我们开始讲【结构型】设计模式,【结构型】设计模式有如下几种:**适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式、代理模式**。【创建型】的设计模式解决的是对象创建的问题,那【结构型】设计模式解决的是类和对象的组合关系的问题。 今天我们就开始讲【结构型】设计模式里面

设计模式学习(七):适配器模式

设计模式学习(七):适配器模式 作者:Grey 原文地址: 博客园:设计模式学习(七):适配器模式 CSDN:设计模式学习(七):适配器模式 适配器模式 适配器模式是一种结构型模式。 举例说明,假设有一个播放器,需要根据不同格式以及对应的文件来播放,接口设计如下: public interface

正则表达式总结-1

转载 正则表达式真的很强,可惜你不会写 正则表达式是一种强大的文本处理工具,它允许你根据一定的规则来搜索、匹配、替换和验证文本,适配各种编程语言。 应用场景 正则表达式在计算机领域有广泛的应用,包括: 1、文本搜索和匹配:查找特定模式的字符串,如搜索包含特定关键词的文档。 2、数据验证:验证用户输入

终极指南!Terraform的进阶技巧

如果您已经对 Terraform 了如指掌,并期望自己的 IaC 技能有进一步提升的话,这篇文章很适合您!在本文中,我们将分享一些 Terraform 的高级使用技巧。从使用模块(module)、工作区(workspace)到管理远程状态存储、自定义 provider等技巧,帮助您轻松、高效地管理基

Falcon-7B大型语言模型在心理健康对话数据集上使用QLoRA进行微调

文本是参考文献[1]的中文翻译,主要讲解了Falcon-7B大型语言模型在心理健康对话数据集上使用QLoRA进行微调的过程。项目GitHub链接为https://github.com/iamarunbrahma/finetuned-qlora-falcon7b-medical,如下所示: 使用领域适

扎克伯格说,Llama3-8B还是太大了,量化、剪枝、蒸馏准备上!

扎克伯格说,Llama3-8B还是太大了,不适合放到手机中,有什么办法? 量化、剪枝、蒸馏,如果你经常关注大语言模型,一定会看到这几个词,单看这几个字,我们很难理解它们都干了些什么,但是这几个词对于现阶段的大语言模型发展特别重要,它们就是将模型缩小的利器。这篇文章就带大家来认识认识它们,理解其中的原