设计模式之适配器模式

456 阅读2分钟

一、概述

  • 适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表示,主要目的是兼容性,让接口不匹配不能工作的两个类可以协同工作,别名为包装类(Wrapper)

二、类适配器模式

  • Adapter类,通过继承src类,实现dst接口,完成src->dst的适配
  • 电源适配器例子:电源适配器VoltageAdapter继承Voltage220V,实现Voltage5V在这里插入图片描述
public class Voltage220V {
  private final static int voltage = 220;

  public static int output220V() {
    return voltage;
  }
}
public interface Voltage5V {
  int output5V();
}
public class VoltageAdapter extends Voltage220V implements Voltage5V {
  @Override
  public int output5V() {
    int vol = output220V();
    int output = vol / 44;
    if (output != 5) throw new RuntimeException("输入电压不符合");
    return output;
  }
}
public interface Phone {
  void charge(Voltage5V voltage5V);
}
  • Java是单继承机制,所以类适配器需要继承src类这一点算是一个缺点,因为这要求dst必须是接口,有一定局限性
  • src类的方法在Adapter中会暴露,也增加了使用的成本
  • 由于继承了src类,所以它可以根据需求重写src类的方法,使得Adapter的灵活性增强

三、对象适配器模式

  • 用关联关系(聚合)来替代继承关系,src类聚合到Adapter类中,而不是继承 在这里插入图片描述
public class VoltageAdapter implements Voltage5V {
  private Voltage220V voltage220V;

  public VoltageAdapter(Voltage220V voltage220V) {
    this.voltage220V = voltage220V;
  }
  public void setVoltage220V(Voltage220V voltage220V) {
    this.voltage220V = voltage220V;
  }

  @Override
  public int output5V() {
    int vol = voltage220V.output220V();
    int output = vol / 44;
    if (output != 5) throw new RuntimeException("输入电压不符合");
    return output;
  }
}
  • 成本更低,更灵活

四、接口适配器模式

  • 又叫适配器模式或缺省适配器模式
  • 核心思路:当不需要实现所有接口提供的方法时,先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。
  • 适用于不想实现接口所有方法的情况。收窄了接口
public interface Interface0 {
  void m1();
  void m2();
  void m3();
  void m4();
}
public abstract class AbsClass implements Interface0{
  @Override
  public void m1() {
    throw new UnsupportedOperationException("Haven't overrider this method!");
  }
  @Override
  public void m2() {
    throw new UnsupportedOperationException("Haven't overrider this method!");
  }
  @Override
  public void m3() {
    throw new UnsupportedOperationException("Haven't overrider this method!");
  }
  @Override
  public void m4() {
    throw new UnsupportedOperationException("Haven't overrider this method!");
  }
}
public class Interface0Impl extends AbsClass {
  @Override
  public void m1() {
    System.out.println("调用m1方法");
  }

  public static void main(String[] args) {
    Interface0 interface0 = new Interface0Impl();
    interface0.m1();  // 调用m1方法
    interface0.m2();  // UnsupportedOperationException
  }
}