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

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

  • 简介
  • 优缺点
  • 应用场景
  • JAVA 代码示例
简介适配器模式(Adapter Pattern)是一种结构型设计模式,它可以将一个接口转换成客户端所期待的另一个接口,从而使原本由于接口不兼容而不能一起工作的类可以一起工作 。适配器模式也称为包装器模式(WrApper Pattern),因为它通过一个包装类(即适配器)来包装不兼容的接口,并提供统一的目标接口 。适配器模式可以在运行时根据需要选择不同的适配器来适配不同的被适配者 。
适配器模式:如何让不兼容的接口变得兼容

文章插图
对象适配器模式的各角色定义如下 。
  • Target(目标接口):客户端要使用的目标接口标准,对应下文中的三相插孔接口 TriplePin 。
  • Adapter(适配器):实现了目标接口,负责适配(转换)被适配者的接口 specificRequest()为目标接口 request(),对应本章下文中的电视机专属适配器类 TriplePinAdapter 。
  • Adaptee(被适配者):被适配者的接口标准,目前不能兼容目标接口的问题接口,可以有多种实现类,对应下文中的两相插孔接口 DualPin 。
  • Client(客户端):目标接口的使用者 。
优缺点适配器模式的优点有:
  • 适配器模式可以增强程序的可扩展性,通过使用适配器,可以在不修改原有代码的基础上引入新的功能或者接口 。
  • 适配器模式可以提高类的复用性,通过使用适配器,可以将已有的类或者接口重新组合和封装,使其符合新的需求 。
  • 适配器模式可以增加类的透明度,通过使用适配器,客户端只需要关注目标接口,而无需了解被适配者的具体实现 。
  • 适配器模式可以灵活地切换不同的被适配者,通过使用不同的适配器,可以动态地选择不同的被适配者来满足不同的场景 。
适配器模式的缺点有:
  • 适配器模式会增加系统的复杂性,过多地使用适配器会使系统变得零乱和难以理解 。
  • 适配器模式可能会降低系统的性能,因为每次调用目标接口时都需要经过适配器的转换 。
  • 适配器模式可能会违反开闭原则,如果目标接口发生变化,则需要修改所有的适配器类 。
应用场景适配器模式适用于以下场景:
  • 当需要在一个已有系统中引入新的功能或者接口时,它与系统的目标接口不兼容,但又不能修改原有代码时,可以使用适配器模式 。例如在一个数据库操作系统中,如果想要支持多种类型的数据库源,但系统只提供了一个固定类型数据库源的操作接口时,可以使用一个数据库源操作适配器来将不同类型数据库源转换成统一类型数据库源 。
  • 当需要在多个独立开发的系统或者组件之间进行协作时,但由于各自采用了不同的接口或者协议时,可以使用适配器模式 。例如在一个分布式服务系统中,如果想要让不同语言编写的服务之间进行通信和调用,但各自采用了不同的通信协议和数据格式时,可以使用一个服务通信适配器来将不同协议和数据格式转换成统一协议和数据格式 。
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 参数 。


    推荐阅读