07 Adapter Pattern(适配器模式)
前言:通过将类的接口转换成想要的接口,以便实现不用的接口。我们的程序可以用新的接口来封装旧的接口,而客户是无感知地调用新接口或者旧接口。
例子说明:
EXP1:港版的苹果手机,用过港版的一定知道,港版手机的充电器是三角粗头的,而大陆的插座则是细头的,这样需要使用港版的充电器的时候就需要有三转二的转接口,这里的转接口实际上就充当适配器的作用。
港版充电头 转接头 大陆插座
REQ1:现在有这么种需求,我们在第一章节曾经写过鸭子类吧,现在我们需要将火鸡包装成鸭子。
分析:先来看看类图,说明火鸡适配器也继承了接口Duck,而火鸡适配器中装配了火鸡,来实现具体的叫和飞的功能。
下面通过代码来实现这个部分,你会发现你将火鸡变成了鸭子来用了。
火鸡适配器:
public class TurkeyAdatpter implements Duck {
private Turkey turkey;
public TurkeyAdatpter(Turkey turkey) {
this.turkey = turkey;
}
public void quack() {
turkey.gobble();
}
public void fly() {
for(int i=0; i<5; i++) {
turkey.fly();
}
}
}
分析:适配器模式非常地简单,实际上就是适配器来调用被适配者的功能。
1 客户通过目标接口调用适配器地方法对适配器发出请求
2 适配器使用被适配者接口把请求转换成被适配者的一个或多个调用接口
3 客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用。
适配器模式:将一个类的接口转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间。
这个模式可以通过创建适配器进行接口转换,让不兼容的接口变成兼容。这可以让客户从实现的接口解耦。
下面是模式的一般类图:
适配器模式很好地运用了OO的设计原则,使用对象组合,以修改的接口包装被适配者。
接下来,我们看看Java中的适配器。早期Collection类型(Vector、Stack、Hashtable)都实现了elements方法,该方法返回一个Enumeration(枚举)。这个Enumeration接口可以遍历集合中的每个元素。后来sun推出更新后的集合类后,开始使用迭代器(Iterator)接口,这个接口和枚举接口很类似,不同的是它还多个删除元素的能力。
在EnumeratorIterator中要处理remove方法,适配器无法实现一个实际功能remove方法,只能抛出一个RuntimeException,Java的设计者也定义了UnsupportedException。
枚举适配器:
public class EnumeratorIterator<E> implements Iterator<E> {
private Enumeration<E> enumer;
public boolean hasNext() {
return enumer.hasNext();
}
public E next() {
return enumer.next();
}
public E remove() {
throw new UnsupportedOperationException();
}
}
最后的最后,我们又来总结我们现在现有的设计模式武器。
面向对象基础
抽象、封装、多态、继承
六大设计原则
设计原则一:封装变化
设计原则二:针对接口编程,不针对实现编程。
设计原则三:多用组合,少用继承。
设计原则四:为交互对象之间的松耦合设计而努力
设计原则五:对扩展开放,对修改关闭
设计原则六:依赖抽象,不要依赖于具体的类
模式
适配器模式:将一个类的接口转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间。
最后献上此次设计的源码,有需要的小伙伴可以下载来运行一下,首先先自己进行设计,然后再参考,这样才能加深命令模式的理解。