适配器模式就是将一个系统的接口转换成另一种形式,从而使原来不能直接调用的接口可以调用。
在上篇文章当中,我们提到了外观模式,外观模式为外系统的调用提供了一个统一的接口,以此来降低系统间的耦合度,那么我们来想一下这样的应用场景,假如有多个外系统要调用子系统的统一接口的某个方法,但是他们所需要的返回值又是不同的类型,比如说有的需要返回string类型,有的需要返回Map类型等,而如果针对每个外系统的调用分别编写一个方法显然不可行,这时我们就可以使用Adapter模式了。
下面我们来看一个例子:
Facade类:
package com.dxy.design.pattern.builder.adapter;
import java.util.ArrayList;
import java.util.List;
public class Facade {
public List getList() {
List list = new ArrayList();
list.add("hello");
list.add("word");
return list;
}
}
而外系统需要的是一个Map类型的值,外系统调用类Application.java:
package com.dxy.design.pattern.builder.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+""));
}
}
}
外系统需要的是Map类型的参数,而子系统返回给我们的是一个List类型,这时我们就可以时候Adapter模式将List类型转换为Map类型Adapter类如下:
package com.dxy.design.pattern.builder.adapter;
import java.util.HashMap;
import java.util.List;
public class Adapter extends HashMap{
private List list;
public Adapter(List list) {
this.list = list;
}
public int size() {
return list.size();
}
public Object get(Object i) {
return list.get(Integer.valueOf(i.toString()).intValue());
}
}
我们就可以在客户端调用:
package com.dxy.design.pattern.builder.adapter;
public class Client {
public static void main(String[] args) {
Facade facade = new Facade();
Adapter adapter = new Adapter(facade.getList());
Application.execute(adapter);
}
}
这样外系统就可以成功使用子系统的方法。spring中的请求分发器,io中的输入输出都使用了Adapter模式。java的api在设计过程中使用了默认的适配器模式:有一个接口,里面定义了很多方法,但在实现类中只需要一个方法,这样就可以定义一个实现了这个接口的抽象类,然后去实现这个抽象类来完成需要的操作:
package com.designpattern.adapter;
public interface Phone {
public void sendMessage();
public void surfInternet();
public void receiveCall();
public void AsAlarm();
}
package com.designpattern.adapter;
public abstract class ChinaMobile implements Phone {
@Override
public void AsAlarm() {
// TODO Auto-generated method stub
}
@Override
public void receiveCall() {
// TODO Auto-generated method stub
}
@Override
public void sendMessage() {
// TODO Auto-generated method stub
}
@Override
public void surfInternet() {
// TODO Auto-generated method stub
}
}
package com.designpattern.adapter;
public class MyPhone extends ChinaMobile {
@Override
public void AsAlarm() {
System.out.println("I just use it as a alarm!");
}
}