适配器模式分两种:类适配器和对象适配,学过这种设计模式了清楚,它可以让一个类的接口转换成客户所期待的接口,从我们拥有的接口中编写代码来产生我们需要的接口,可以是代码更泛化,从而就接近与其潜在类型机制了。
代码例子:
泛型类型参数类代码:
//公共父类
public class Coffee
{
private static long counter = 0;
//标记每个子类的标识值
private final long id = counter++;
public String toString()
{
return getClass().getSimpleName() + " " + id;
}
}
public class Latte extends Coffee {}
public class Mocha extends Coffee {}
目标接口:
interface Addable<T> { void add(T t); }
源角色:
public class SimpleQueue<T> implements Iterable<T> {
private LinkedList<T> storage = new LinkedList<T>();
public void add(T t) { storage.offer(t); }
public T get() { return storage.poll(); }
public Iterator<T> iterator() {
return storage.iterator();
}
}
适配器:
//对象适配器,把任何Collection类都适配为Addable接口
public class AddableCollectionAdapter<T> implements Addable<T> {
//源角色
private Collection<T> c;
public AddableCollectionAdapter(Collection<T> c) {
this.c = c;
}
public void add(T item) { c.add(item); }
}
//类适配器,把SimpleQueue类适配为Addable接口
public class AddableSimpleQueue<T> extends SimpleQueue<T> implements Addable<T> {
public void add(T item) { super.add(item); }
}
代码测试:
class Adapter {
public static <T>
Addable<T> collectionAdapter(Collection<T> c) {
//这里利用了捕获转换,有利于捕获其泛型类型参数
return new AddableCollectionAdapter<T>(c);
}
}
public class Fill2Test {
public static void main(String[] args) {
// 创建一个容器类源角色
List<Coffee> carrier = new ArrayList<Coffee>();
Fill2.fill(
new AddableCollectionAdapter<Coffee>(carrier),
Coffee.class, 3);
Fill2.fill(Adapter.collectionAdapter(carrier),
Latte.class, 2);
for(Coffee c: carrier)
System.out.println(c);
System.out.println("----------------------");
// 创建一个适配器
AddableSimpleQueue<Coffee> coffeeQueue =
new AddableSimpleQueue<Coffee>();
Fill2.fill(coffeeQueue, Mocha.class, 4);
Fill2.fill(coffeeQueue, Latte.class, 1);
for(Coffee c: coffeeQueue)
System.out.println(c);
}
}
运行结果:
Coffee 0
Coffee 1
Coffee 2
Latte 3
Latte 4
Mocha 5
Mocha 6
Mocha 7
Mocha 8
Latte 9