定义
适配器模式(adapter pattern)将一个类的接口,转换成客户期望的另外一个接口。适配器让原本不兼容的类可以合作无间。
上图清晰地表述了适配器模式的威力,通过创建适配器接口,现有的系统可以不用修改代码就可以通过适配器接口调用厂商类,现有的系统和厂商类之间可以很好地协作。
适配器模式让不兼容的接口变成兼容,还可以让客户从厂商类的实现中解耦,当厂商类改变时,适配可以封装变化,客户代码不需要跟着变化。

适配器模式分为两种:对象适配器和类适配器。从上面的类图可以看出,对象适配器利用组合的方式将请求传送给被适配器。类适配器使用了多重继承,同时继承了Target和Adaptee类。
代码实现
下面以JDK中的例子来说明适配器模式。
JDK 1.0的集合(collection)类型(例如: Vector,Stack,Hashtable)都实现了一个名为elements()的方法,该方法返回一个Enumeration。Enumeration的定义如下:
public interface Enumeration<E> {
boolean hasMoreElements();
E nextElement();
}
JDK 1.2引入了Iterator接口:
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
}
在面对遗留代码,这些代码暴露出Enumeration接口,但是我们又希望在新的代码中只使用Iterator接口。想解决这个问题,我们需要构造一个适配器,将Enumeration适配到Iterator:
import java.util.*;
public class EnumerationIterator implements Iterator {
Enumeration enumeration;
public EnumerationIterator(Enumeration enumeration) {
this.enumeration = enumeration;
}
public boolean hasNext() {
return enumeration.hasMoreElements();
}
public Object next() {
return enumeration.nextElement();
}
public void remove() {
throw new UnsupportedOperationException();
}
}
客户代码:
import java.util.*;
public class EnumerationIteratorTestDrive {
public static void main (String args[]) {
Vector v = new Vector(Arrays.asList(args));
// iterator是实现了Iterator接口的适配器
Iterator iterator = new EnumerationIterator(v.elements());
// 客户代码只要调用Iterator的接口API接口,不用关心适配器的实现
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
该模式体现了哪些OO原则
-
在对象适配器中,client针对接口编程。
在类适配器中,client针对子类Target编程,不针对具体的实现Adapter编程。 -
在对象适配器中,适配器使用对象组合的方式,委托给被适配器。
本章总结
适配器模式和装饰者模式的区别:
适配器模式强调的是对接口的转换,让原来不兼容的接口变成兼容的。装饰者模式则强调通过对对象的封装来增强原对象的功能,所以装饰者一定会在原对象的基础上增加新的功能,而适配器模式重点在接口转换,不一定会增加新的功能
适配器模式和外观模式的差别:
两种模式都是对其它的接口的再次封装。差别在适配器强调对一个或者多个接口的转换,而外观模式则强调简化接口