适配器模式
目的
将一个接口转换为另一个接口,可以使其不改变源代码的接口,就可以将两个不兼容的接口适配。
定义
适配器模式将一个类的接口转换成客户期望的另一个接口,适配器让原本不兼容的类可以合作无间
要点与源码
客户使用适配器的过程
- 客户通过目标接口调用适配器的方法对适配器发出请求。
- 适配器使用被适配者接口把请求转换成被适配者的一个或多个调用接口。
- 客户接受到调用的结果,但并未察觉这一切是适配器在起转换作用。
代码 (HeadFirst设计模式)
public interface Duck{
public void quark();
public void fly();
}
public class MallardDuck implements Duck {
public void quark() {
System.out.println("Quark");
}
public void fly() {
System.out.println("I'm flying");
}
}// 上述为鸭子接口和鸭子类
public interface Turkey {
public void gobble();
public void fly();
}
public class WildTurkey implements Turkey{
public void gobble() {
System.out.println("Gobble gobble");
}
public void fly(){
System.out.println("I'm flying a short distance");
}
}// 上述为火鸡接口和火鸡实现类
public class TurkeyAdapter implements Duck{// 实现转换成的适配接口.
Turkey turkey;
public TurkeyAdapter(Turkey turkey) {//需要取得要适配的对象的引用
this.turkey=turkey;
}
public void quack(){
turkey.gobble();
}
public void fly() {
for(int i=0;i<5;i++){
turkey.fly();
}
}
}
public class DuckTestDrive {
public static void main(String[] args) {
MallardDuck duck = new MallardDuck();
WildTurkey turkey = new WildTurkey();
Duck turkeyAdapter = new TurkeyAdapter(turkey);
System.out.println("The Turkey says...");
turkey.gobble();
turkey.fly();
System.out.println("\nThe Duck says...");
testDuck(duck);//这里传入真实的鸭子
System.out.println("\nThe TurkeyAdapter says...");
testDuck(turkeyAdapter);//这里传入鸭子适配器
}
static void testDuck(Duck duck) {//传入的参数既可以是真实的鸭子,也可以是鸭子适配器的火鸡。
duck.quack();
duck.fly();
}
}
对象适配器与类适配器
对象适配器继承某一个需要适配的类,被适配的类通过组合的方式进行转换。如上例所示,适配器实现了鸭子的接口,但是在方法得到调用时,会将接口委托给火鸡。
类适配器通过多继承的方式来进行扩展,在Java中不适用。
适配器的具体应用(在Headfirst设计模式,Java中)
枚举器向迭代器的适配
在老版本的Java中,早期的集合类实现了一个elements()的方法,该方法会返回一个Enumeration接口,这个接口可以逐一走过集合内的每个元素,在Sun公司推出更新后的集合类时,开始使用了Iterator接口,这个接口和枚举接口很像,都可以让遍历此集合类型内的每个元素,但不同的是迭代器好提供了删除元素的能力。
如何将枚举适配到迭代器,是其能够在新的代码中只使用迭代器不使用枚举,达到一种统一规范。
接口Enumeration定义了两个方法,分别为hasMoreElements()和nextElement() ,iterator接口定义了三个方法,分别为hasNext(),next(),remove()。通过观察可以得到hasMoreElements() 与hasNext功能相近,nextElements() 与next功能相近,从而
可以如下设计对象适配器
public class EnumerationIterator implements Iterator {
Enumeration enum; // 通过组合的方式,将适配者与被适配者相关联
public EnumerationIterator(Enumeration enum) {
this.enum = enum;
}
public boolean hasNext() {
return enum.hasMoreElements();//当调用Iterator的hasNext方法时,返回枚举的hasMoreElements() ,下面的next相同
}
public Object next() {
return enum.nextElement();
}
public void remove(){
throw new UnsupportedOperationException(); //由于Enumeration没有相应的方法,所以在调用此方法时抛出异常
}
}