将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式
适配器模式
使用场景
- 系统需要使用一些现有的类,而这些类的接口(如方法名)不符合系统的需要,甚至没有这些类的源代码。
 
- 想创建一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
 
优点
- 可以让任何两个没有关联的类一起运行。
 
- 提高了类的复用。
 
- 增加了类的透明度。
 
- 灵活性好。
 
缺点
- 过多的使用适配器,会让系统很凌乱,明明调用的这个接口的方法,里面的实现却是另一个方法
 
- java 最多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
 
实现
- 再来一个好理解的例子,我们国家的民用电都是 220V,日本是 110V,而我们的手机充电一般需要 5V,这时候要充电,就需要一个电压适配器,将 220V 或者 100V 的输入电压变换为 5V 输出
 
电压接口
1 2 3 4 5 6 7
   | public interface AC {     
 
 
      int outputAC(); }
  | 
 
电压实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | public class AC110 implements AC {
      @Override     public int outputAC() {         int ac = 110;         return ac;     } }
  public class AC220 implements AC {
      @Override     public int outputAC() {         int ac = 220;         return ac;     } }
  | 
 
适配器接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | public interface DC5Adapter {
      
 
 
 
      boolean support(AC ac);
      
 
 
 
      int outputDC5V(AC ac); }
  | 
 
适配器实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
   | public class ChinaPowerAdapter implements DC5Adapter {
      public static final int voltage = 220;
      @Override     public boolean support(AC ac) {         return (voltage == ac.outputAC());     }
      @Override     public int outputDC5V(AC ac) {         int adapterInput = ac.outputAC();                  int adapterOutput = adapterInput / 44;         System.out.println("使用ChinaPowerAdapter变压适配器,输入AC:" + adapterInput + "V" + ",输出DC:" + adapterOutput + "V");         return adapterOutput;     } }
  public class JapanPowerAdapter implements DC5Adapter {     public static final int voltage = 110;
      @Override     public boolean support(AC ac) {         return (voltage == ac.outputAC());     }
      @Override     public int outputDC5V(AC ac) {         int adapterInput = ac.outputAC();                  int adapterOutput = adapterInput / 22;         System.out.println("使用JapanPowerAdapter变压适配器,输入AC:" + adapterInput + "V" + ",输出DC:" + adapterOutput + "V");         return adapterOutput;     } }
  | 
 
手机充电器类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
   | public class Charger {
      private List<DC5Adapter> adapters = new LinkedList<>();
      public Charger() {         this.adapters.add(new ChinaPowerAdapter());         this.adapters.add(new JapanPowerAdapter());     }
      
 
 
 
      public int convertAC(AC ac) {         DC5Adapter adapter = null;         for (DC5Adapter ad : this.adapters) {             if (ad.support(ac)) {                 adapter = ad;                 break;             }         }         if (adapter == null){             throw new  IllegalArgumentException("没有找到合适的变压适配器");         }         return adapter.outputDC5V(ac);     } }
  | 
 
测试如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
   | public class AdapterTest {
      
 
 
      @Test     public void testBasic1() throws Exception{         Adapter adapter = new Adapter();
          adapter.request();     }
 
      
 
 
      @Test     public void testBasic2()throws Exception{         Adapter2 adapter = new Adapter2();
          adapter.request();
      }
      
 
 
 
 
 
      @Test     public void testCharger() throws Exception{
          AC chinaAC = new AC220();         Charger charger = new Charger();         System.out.println("220V电压 充电 转换后的电压为:"+charger.convertAC(chinaAC));
 
                   AC japanAC = new AC110();         System.out.println("110V电压 充电 转换后的电压为:"+charger.convertAC(japanAC));     } }
  | 
 
个人理解
想复用现有接口或者方法签名,但是需要增加额外功能时使用适配器模式