火鸡冒充鸭子
现在缺少一个绿头鸭对象,需要用野生火鸡对象冒充一下,但是二者的接口都不一样该怎么去冒充呢?
// 鸭子接口
public interface Duck{
public void quack(); // 呱呱叫
public void fly(); // 飞行
}
// 火鸡接口
public interface Turkey{
public void gobble(); // 咯咯叫
public void fly(); // 飞行
}
// 野生火鸡
public class WildTurkey implements Turkey{
public void gobble(){
System.out.println("gobble");
}
public void fly(){
System.out.println("short flying");
}
}
写个适配器
public class TurkeyAdapter implements Duck{ // 实现目标接口(因为想要一个鸭子对象,所以要实现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 DuckTest{
public static void main(String[] args){
WildTurkey turkey = new WildTurkey();
Duck turkeyAdapter = new TurkeyAdapter(turkey); // 开始冒充
// 还是和鸭子一样能调用相应的方法,冒充成功
turkeyAdapter.quack();
turkeyAdapter.fly();
}
}
适配器模式
- 适配器模式将一个类的接口转换为客户期望的另一个接口,也就让原本接口不兼容的类可以合作
- 将适配器模式类推到上述火鸡鸭子例子,如下图所示:
- 客户使用适配器的流程:
- 客户通过目标接口调用适配器的方法
- 适配器使用被适配者接口把请求转换为被适配者的一/多个接口
- 客户接收到调用结果时并不知道适配器进行了转换
- 客户和被适配者是解耦的,它们之间并不知道对方
从枚举适配到迭代器
在早期的Java集合类型中存在一个
Enumeration
接口,其中有hashMoreElements
和nextElement
方法,而在更新后的Java集合类中开始使用Iterator
接口,其中的方法是hashNext
、next
和remove
,现在希望在新代码中只使用迭代器,该如何实现?
设计适配器
public class EnumerationIterator implements Iterator{ // Iterator是目标接口
Enumeration enum; // Enumeration就是被适配的接口,使用组合的方式
public EnumerationIterator(Enumeration enum){
this.enum = enum;
}
public boolean hasNext(){ // 委托给enum的hashMoreElements方法
return enum.hashMoreElements();
}
public Object next(){
return enum.nextElement(); // 同理
}
public void remove(){
return new UnsupportedOperationException(); // 无法支持,只能抛个异常
}
}
参考
Head First 设计模式-适配器模式
设计模式-适配器模式