Adapter Pattern(适配器模式)

原文

别称

包装器适配器

目的

将接口转换成客户希望的另一个接口。适配器能让接口不兼容的类工作在一起。

译者补充: 适配器模式在详细设计阶段不需要考虑它,它是为了对现有系统或产品接口兼容时,也就是既成事实的情况下的补救措施。

解释

生活上的案例

假设你需要将SD卡上的照片传到电脑里,但你的电脑不能直接连接SD卡。这时候,你需要一个读卡器,SD卡插在读卡器,读卡器通过USB插到电脑,这样,你就可以将照片传到电脑了。这里,读卡器就是一种适配器。电源转换器是另一个适配器案例,比如 香港买的电子产品是 三正脚,而大陆仅支持三斜脚,为连接电源就需要电源转换器了。还有一个案例: 翻译者将一种语言转换成另一种语言表达。

白话

适配器模式就是将不兼容的对象通过适配器封装,使得其跟其他对象兼容

维基百科

在设计模式中,适配器模式(英语:adapter pattern)有时候也称包装样式或者包装(wrapper)。将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类能在一起工作,做法是将类自己的接口包裹在一个已存在的类中。

编程实例

假设有这样一个船长,只会皮筏艇,不会用帆船/渔船。
这里我们定义接口'RowingBoat'和'FishingBoat'

public interface RowingBoat {
  void row();
}

public class FishingBoat {
  private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class);
  public void sail() {
    LOGGER.info("The fishing boat is sailing");
  }
}

船长实现了RowingBoatinterface

public class Captain implements RowingBoat {

  private RowingBoat rowingBoat;

  public Captain(RowingBoat rowingBoat) {
    this.rowingBoat = rowingBoat;
  }

  @Override
  public void row() {
    rowingBoat.row();
  }
}

这时候海盗来了,我们的船长需要逃跑,但现在只有一艘渔船。我们需要创建一个适配器,让船长可以操作渔船

public class FishingBoatAdapter implements RowingBoat {

  private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class);

  private FishingBoat boat;

  public FishingBoatAdapter() {
    boat = new FishingBoat();
  }

  @Override
  public void row() {
    boat.sail();
  }
}

现在,我们的船长可以使用渔船逃跑了

Captain captain = new Captain(new FishingBoatAdapter());
captain.row();

适用的场景

遇到以下场景,考虑使用适配器模式:

  • 你想使用现有的一个类,但其接口不匹配你使用的
  • 你想创建一个可以复用的类,需要和不相干的或者不可预见的类,就是,没有统一兼容接口的类
  • 你想使用好几个已存在的子类,通过继承每个子类的方式来适配是不切实际的。对象适配器能够调整其父类的接口
  • 当系统使用很多第三方组件,通过适配器作为该应用和第三方组件的中间层,可以做到解耦。如果新增一个第三方,只要新增一个对应的适配器就可以使用,而不需要修改系统

两种适配器

类适配器和对象适配器之前的差异。

类适配器: 这种适配器模式下,适配器继承自已实现的类(一般多重继承)。

  • 类适配器将具体的类作为被适配者,这样导致需要适配所有子类时 就不能用了
  • 因为是子类,所以可以修改被适配者的行为
  • 只有一个实例,无法引用到被适配者
15319940547657.jpg

对象适配器: 在这种适配器模式中,适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。

  • 一个对象适配器,可以用于多个被适配者--所有子类,还可以给所有子类添加新的功能方法
  • 很难修改被适配者的行为
15319946178314.jpg

真实的案例

  • java.util.Arrays#asList()
  • java.util.Collections#list()
  • java.util.Collections#enumeration()
  • javax.xml.bind.annotation.adapters.XMLAdapter

你可能感兴趣的:(Adapter Pattern(适配器模式))