1.你可能会经常遇到下面这种情况,厂家提供的接口和你写的接口合不上,怎么办??
这时候你不想改变自己的接口来适应厂家的接口,同时你又不能改变厂家的接口,那么这个时候你就应该考虑使用适配器模式了。
厂家调用他们的接口,而实际上我们给的却是看似像厂家的接口的接口。
2.适配器模式( Adapter Pattern)把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。又称为转换器模式、变压器模式、包装模式
模式所涉及的角色有:
目标(Target)角色:所期待得到的接口。
源(Adaptee)角色:需要适配的接口。
适配器(Adapter)角色:适配器把源接口转换成目标接口。根据这一角色的实现不同,可分为类的适配器模式(使用继承实现)和对象的适配器模式(使用委派关系实现)
3.例子: List -> Map
package com.adapter;
import java.util.ArrayList;
import java.util.List;
public class Facade {
public List getEmpByOrgan(String orgId){
List list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
return list;
}
}
package com.adapter;
import java.util.HashMap;
import java.util.List;
public class ListMapAdapter extends HashMap {
private List list;
public ListMapAdapter(List list){
this.list = list;
}
@Override
public Object get(Object i) {
return list.get(Integer.valueOf(i.toString()).intValue());
}
@Override
public int size() {
return list.size();
}
}
package com.adapter;
import java.util.HashMap;
public class Application {
public static void execute(HashMap map){
for(int i = 0; i< map.size(); i++){
System.out.println(map.get(i+""));
}
}
}
package com.adapter;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
Facade facade = new Facade();
ListMapAdapter listAdapter = new ListMapAdapter(facade.getEmpByOrgan(""));
Application.execute(listAdapter);
}
}
4.UML
5.类适配器与对象适配器
a.类的适配器模式把适配的类的API转换成目标类的API
例子:
/** * 定义Client使用的与特定领域相关的接口 */ public interface Target { void sampleOperation1(); void sampleOperation2(); } /** * 定义一个已经存在的接口,这个接口需要适配 */ public class Adaptee { public void sampleOperation1() { // ...... } } /** * 对Adaptee与Target接口进行适配 */ public class Adapter extends Adaptee implements Target { public void sampleOperation2() { // ...... } }
b. 与类的适配器模式一样,对象适配器模式把适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。
例子:
/** * 定义Client使用的与特定领域相关的接口 */ public interface Target { void sampleOperation1(); void sampleOperation2(); } /** * 定义一个已经存在的接口,这个接口需要适配 */ public class Adaptee { public void sampleOperation1() { // ...... } } /** * 对Adaptee与Target接口进行适配 */ public class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee) { super(); this.adaptee = adaptee; } public void sampleOperation1() { adaptee.sampleOperation1(); } public void sampleOperation2() { // ...... } }
使用组合可以让你最大限度的减少对adaptee的依赖。因此,建议在能使用对象适配器的时候不使用继承的方式。