什么是适配器
现实中的适配器是把作为两个无法适配的设备之前的桥梁,把一个设备转化成另一个设备可以使用的设备,类似的,假设已有一个软件系统,你希望它能和一个新的厂商类库搭配使用,但是这个新厂商所设计出来的接口,不同于旧厂商的接口,如果不希望改变代码,就可以写一个适配器类,将新厂商接口转接成你所希望的接口。
适配器的正式定义
适配器模式是将一个类的接口,转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间。
下面是一个适配器的例子:
假设有一个Duck接口和Turkey接口,都包含叫和飞的方法,如下所示:
public interface Duck {
public void quack();
public void fly();
}
public interface Turkey {
public void gobble();
public void fly();
}
可以用一个适配器把Turkey对象转换为Duck对象:
public class TurkeyAdapter implements Duck {
Turkey turkey;
public TurkeyAdapter(Turkey turkey){
this.turkey = turkey;
}
@Override
public void quack() {
turkey.gobble();
}
@Override
public void fly() {
turkey.fly();
}
}
只要在适配器的构造器里调用火鸡对象就可以实例化一个鸭子对象了。
模式分析
适配器模式包括以下角色:客户(client)、目标接口(target)、适配器(adapter)、被适配者(adaptee)。
客户使用适配器的过程:
- 适配器实现了目标接口(duck),并持有被适配者(turkey)的实例;
- 客户通过目标接口调用适配器的方法对适配器发出请求;
- 适配器使用被适配者接口把请求转换成被适配者的一个或多个调用接口;
- 客户接收到调用的结果,但并不知道是适配器起转换作用。
真实世界的适配器
JAVA早期集合类都实现了一个elements()的方法,返回一个Enumeration,可以遍历集合的每个元素,而现在的集合类使用迭代器实现这一功能,但是有一些遗留代码,它们暴露出枚举器接口,这时,可以用一个适配器把枚举器转换为迭代器。实现如下:
public class EnumerationIterator implements Iterator {
Enumeration enumeration;
public EnumerationIterator(Enumeration enumeration){
this.enumeration = enumeration;
}
@Override
public boolean hasNext() {
return enumeration.hasMoreElements();
}
@Override
public Object next() {
return enumeration.nextElement();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
什么是外观模式
外观模式的定义:
外观模式提供了一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层接口,让子系统更容易使用。
举个例子,一个家庭影院系统的开启包括许多动作:把灯光调暗、打开投影仪、打开DVD播放器等等,这些过程太繁琐,可以创建一个外观类,封装几个简单的方法,例如watchMovie、endMovie等,只需要调用一个方法就可以包含所有操作,更加方便。
外观和适配器都可以包装许多类,但是外观的意图是简化接口,而适配器的意图是讲接口转换成不同接口。