Adapter:适配器
Adapter设计模式正如名字所说的,起着适配器的作用。交流电供应220V,但是我们手机充电需要直流5V,这个时候适配器就起作用了,将电源供应转换成能够被我们手机所使用的伏特。
至此我们明白适配器模式的意图
意图:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适用性:
以下情况使用Adapter模式:
1 • 你想使用一个已经存在的类,而它的接口不符合你的需求。
2 • 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
3 •(仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。即仅仅引入一个对象,并不需要额外的指针以间接取得adaptee。
适配器的种类:
共有两类适配器模式:1.类的适配器模式(采用继承实现)2.对象适配器(采用对象组合方式实现)
1)类适配器模式
——适配器继承自已实现的类(一般多重继承)。
Adapter与Adaptee是继承关系
1、用一个具体的Adapter类和Target进行匹配。结果是当我们想要一个匹配一个类以及所有它的子类时,类Adapter将不能胜任工作
2、使得Adapter可以重定义Adaptee的部分行为,因为Adapter是Adaptee的一个子集
3、仅仅引入一个对象,并不需要额外的指针以间接取得adaptee
2)对象适配器模式—— 适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。
Adapter与Adaptee是委托关系
1、允许一个Adapter与多个Adaptee同时工作。Adapter也可以一次给所有的Adaptee添加功能
2、使用重定义Adaptee的行为比较困难
无论哪种适配器,它的宗旨都是:保留现有类所提供的服务,向客户提供接口,以满足客户的期望。
即在不改变原有系统的基础上,提供新的接口服务。
结构:
类适配器:
类适配器使用多重继承对一个接口与另一个接口进行匹配。
对象适配器:
对象匹配器依赖于对象组合
构建模式的组成
•目标角色(Target):— 定义Client使用的与特定领域相关的接口。
• 客户角色(Client):与符合Target接口的对象协同。
• 被适配角色(Adaptee):定义一个已经存在并已经使用的接口,这个接口需要适配。
• 适配器角色(Adapte) :适配器模式的核心。它将对被适配Adaptee角色已有的接口转换为目标角色Target匹配的接口。对Adaptee的接口与Target接口进行适配.
talk is cheap, show me the code:
假设我们有一个随机数组生成器,但我们的客户角色要使用二分搜索一个随机数组。
二分搜索的前提是数组是有序的,这个时候我们的随机数组生成器似乎排不上用场了。
我们也许可以自己再写一个有序随机数组生成器,但是既然我们有现成的随机数组生成器,为什么不稍微改进一下,使其能够产生有序随机数组呢?
随机数组生成器:(被适配角色)
class UnorderedRandomNumberArrayGenerator {
public int[] generateRandomSequence() {
int len = (int) (Math.random() * 20) + 1;
int[] arr = new int[len];
for (int i = 0; i < len; i++) {
arr[i] = (int) (Math.random() * 100);
}
return arr;
}
}
对于类适配器来说,我们要继承被适配的对象,然后实现目标角色的接口。
目标角色接口:
interface OrderedSequenceAdapter {
public int[] generateOrderedSequence();
}
类适配器:
class OrderedRandomNumberArrayGenerator extends UnorderedRandomNumberArrayGenerator implements OrderedSequenceAdapter {
@Override
public int[] generateOrderedSequence() {
int[] arr = generateRandomSequence();
Arrays.sort(arr);
return arr;
}
}
而我们的对象适配器则是通过持有被适配角色:
class OrderedRandomNumberArrayGenerator implements OrderedSequenceAdapter {
private UnorderedRandomNumberArrayGenerator randomNumberArrayGenerator = null;
public OrderedRandomNumberArrayGenerator(UnorderedRandomNumberArrayGenerator randomNumberArrayGenerator) {
this.randomNumberArrayGenerator = randomNumberArrayGenerator;
}
@Override
public int[] generateOrderedSequence() {
int[] arr = randomNumberArrayGenerator.generateRandomSequence();
Arrays.sort(arr);
return arr;
}
}
对于适配器模式,适配器模式只是将原来的接口进行一些调整,使的不兼容的接口能够兼容,他并不会增加新的功能。
在上述随机数组发生器中,被适配类 产生的是无序随机数组,而适配器产生的则是有序随机数组,本质上都是产生随机数组,对于功能上并没有增加。
spring aop框架对BeforeAdvice、AfterAdvice、ThrowsAdvice三种通知类型的支持实际上是借助适配器模式来实现的,这样的好处是使得框架允许用户向框架中加入自己想要支持的任何一种通知类型,上述三种通知类型是spring aop框架定义的,它们是aop联盟定义的Advice的子类型。
public interface AdvisorAdapter {
// 将一个Advisor适配成MethodInterceptor
MethodInterceptor getInterceptor(Advisor advisor);
// 判断此适配器是否支持特定的Advice
boolean supportsAdvice(Advice advice);
}
这个接口允许扩展spring aop框架,以便处理新的Advice或Advisor类型,其实现对象可以把某些特定的Advice类型适配成AOP联盟定义的MethodInterceptor,并在spring aop框架中启用这些通知类型。通常spring用户不需要实现这个接口,除非想把更多的Advice和Advisor引入到spring中时。
spring aop框架本身为这个接口提供了很好的实现,例如为了支持MethodBeforeAdivce、AfterReturningAdvice、以及ThrowsAdvice这三种通知类型,spring在org.springframework.aop.framework.adapter包中分别为它们定义了相应的适配器,在此仅以AfterReturningAdviceAdapter为例
class AfterReturningAdviceAdapter implements AdvisorAdaptor, Serializable {
// 此适配器仅支持AfterReturningAdivce类型
public boolean supportsAdvice(Advice advice) {
return advice instanceof AfterReturningAdivce;
}
// 把特定的Advisor适配成MethodInterceptor
public MethodInterceptor getInterceptor(Advisor advisor) {
AfterReturningAdivce advice = (AfterReturningAdivce) advisor.getAdvice();
return new AfterReturningAdviceInterceptor(advice);
}
}