1. 定义

将一个接口转换成客户希望的另一个接口,使接口不兼容的类可以一起工作,其别名为包装器。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

适配器模式分为类适配器模式和对象适配器模式,由于Java 不支持多重继承,提倡多用组合少用继承,所以本文主要介绍对象适配器。

2. 作用

简言之就是接口转换,比如日常生活中,iPhone 使用 Lightning 接口充电,Android 手机使用 MicroUsb 接口。如果我们想用带 MicroUsb 接口的线给 iPhone 充电怎么办?自然是找个转接头,让电流从 MicroUsb 接口流向 Lightning 接口。这样,转接头就是个适配器,让本来不能一起使用的 MicroUsb 接口和 iPhone 可以友好相处啦。

3. 结构

适配器模式包含如下角色:

  • Target:目标抽象类
  • Adapter:适配器类
  • Adaptee:适配者类
  • Client:客户类

4. 实现

类图
  1. 目标抽象类,就是 iPhone 要使用的 Lightning 接口。

    public interface ILightningInterface {
        /**
         * 充电
         */
        void charge();
    }
    
  2. 适配器类,转接头把 MicroUsb 接口转换为 Lightning 接口。

    public class InterfaceAdapter implements ILightningInterface {
        private MicroUsbInterface microUsbInterface;
    
        public InterfaceAdapter(MicroUsbInterface microUsbInterface) {
            this.microUsbInterface = microUsbInterface;
        }
    
        @Override
        public void charge() {
            microUsbInterface.charge();
        }
    }
    
  3. 适配者类,要适配的 MicroUsb 接口。

    public class MicroUsbInterface {
    
        public void charge() {
            System.out.println("charge with MicroUsb");
        }
    }
    
  4. 客户类,有了转接头,iPhone 也可以使用 MicroUsb 线充电啦。

    public class AdapterTest {
    
        public static void main(String[] args) {
            // 直接使用 Lightning 充电口
            ILightningInterface lightningInterface = new LightningInterface();
            lightningInterface.charge();
    
            // 使用转接头把 MicroUsb 接口转换为 Lightning 接口
            MicroUsbInterface microUsbInterface = new MicroUsbInterface();
            ILightningInterface interfaceAdapter = new InterfaceAdapter(microUsbInterface);
            interfaceAdapter.charge();
        }
    }
    

5. 优缺点

1. 优点:

  • 将目标类和适配者类解耦,增加了类的透明性和复用性;
  • 系统的灵活性和扩展性都非常好,更换适配器或者增加新的适配器都非常方便,符合「开闭原则」。

2. 缺点:

过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。

3. 使用场景:

  • 系统需要使用现有的类,而这些类的接口不符合系统的需要;
  • 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的类一起工作。

参考资料: