上图为适配器模式的对象适配器模式和类适配器模式。
适配器模式所涉及的角色包括:
1. 源(Adaptee):已经存在的、需要适配的类。
2. 目标(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
3. 适配器(Adapter):适配器模式的核心类。有两种方式实现Adapter,对象适配器(Object Adapter)和类适配器(Class Adapter)。
4. 客户(Client):
对象适配器模式:
举个head first上的例子,在java早起版本的集合(collection)类型(e.g:Vector, HashTable)都实现了一个elements方法,此方法返回Enumeration对象。这个Enumeration可以逐个遍历集合的内容。
Enumeration的源码为:
public interface Enumeration<E> {
boolean hasMoreElements();
E nextElement();
}
后来sun公司推出了新的集合类型,开始使用Iterator接口,此借口和Enumeration接口类似,都可以遍历集合内部的元素,同时Iterator还提供了删除功能。
Iterator的源码为:
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
面对遗留的代码,这些代码暴露出老的枚举器的接口,我们希望在新的代码中使用Iterator(迭代器),这里我们需要一个构造器。
public class EnumerationAdapter<K> implements Iterator<K>{
private Enumeration<K> enumeration;
public EnumerationAdapter(Enumeration<K> enumeration){
this.enumeration = enumeration;
}
@Override
public boolean hasNext() {
return enumeration.hasMoreElements();
}
@Override
public K next() {
return enumeration.nextElement();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
因为枚举器接口没有remove方法的实现,这里抛出了UnSupprotOperationException(作为好的习惯,在适配器的要说明这个异常)。
测试程序:
public class TestObjectAdapter {
public static void main(String[] args) {
Vector<Integer> ints = new Vector<Integer>(Arrays.asList(new Integer[]{5, 10}));
Iterator<Integer> iterator = new EnumerationAdapter<Integer>(ints.elements());
while (iterator.hasNext()) {
Integer type = iterator.next();
System.out.println(type);
}
}
}
类适配器模式:
class Adaptee {
publicvoid specificRequest() {
System.out.println("被适配类具有特殊功能...");
}
}
// 目标接口,或称为标准接口
interface Target {
publicvoid request();
}
// 具体目标类,只提供普通功能
class ConcreteTarget implements Target {
publicvoid request() {
System.out.println("普通类具有普通功能...");
}
}
// 适配器类,继承了被适配类,同时实现标准接口
class Adapter extends Adaptee implements Target {
publicvoid request() {
super.specificRequest();//特殊调用
}
}
// 测试类
publicclassClient {
publicstaticvoid main(String[] args) {
// 使用特殊功能类,即适配类
Target adapter = new Adapter();
adapter.request();
}
}
类适配模式和对象适配器模式的区别:
1.对象适配器利用组合的方式,将请求传送给被适配者。
类适配器通过多重继承的方式。
2.由于对象适配器的组合方式,其可以适配某个类,也可以适配该类的任何子类。类适配器只可适配特定的类。
3.类适配器不需要重新实现整个被适配者。(这一句出自head first dp,不太懂,请各位指教)