乐趣区

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

在软件开发中,咱们常常会遇到这样的状况:咱们须要应用一个现有的类或者接口,但它与咱们零碎的指标接口不兼容,而咱们又不能批改它。这时候,咱们该怎么办呢?大多数状况下咱们都能够应用适配器模式来解决这个问题,本文将从以下四个方面解说适配器模式

  • 简介
  • 优缺点
  • 利用场景
  • 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】每周分享技术干货、开源我的项目、实战经验、国外优质文章翻译等,您的关注将是我的更新能源!

退出移动版