一句话概括:有点数据类型转化辅助类的意思。
适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)。
需要被适配的类、接口、对象(我们有的),简称 src(source)
最终需要的输出(我们想要的),简称 dst (destination,即Target)
适配器称之为 Adapter 。
一句话描述适配器模式的感觉: src->Adapter->dst, 即src以某种形式(三种形式分别对应三种适配器模式)给到Adapter里,最终转化成了dst。
适配器设计模式的一个非常实际的例子是电源适配器。 手机电池充电电压是3伏,但正常插座可以产生120V(美国)、240V(印度)、220V(中国)等。 因此,电源适配器可作为移动充电器和墙上插座之间的适配器。
接下来我们尝试使用适配器模式实现多适配器。
//电压
public class Volt {
private int volts;
public Volt(int v){
this.volts=v;
}
public int getVolts() {
return volts;
}
public void setVolts(int volts) {
this.volts = volts;
}
}
//墙上的插座,输出120V电压
public class Socket {
public Volt getVolt(){
return new Volt(120);
}
}
现在我们要构建一个可产生3伏,12伏和默认120伏的适配器。所以首先我们创建一个适配器接口。
public interface SocketAdapter {
public Volt get120Volt();
public Volt get12Volt();
public Volt get3Volt();
}
Two Way Adapter Pattern
在实现适配器模式时,有两种方法 - 类适配器和对象适配器 - 但是这两种方法都会产生相同的结果。
- 类适配器(Class Adapter) - 这种形式使用JAVA继承(java inheritance)并扩展了原始接口,在我们的例子中是Socket类。
- 对象适配器(Object Adapter) - 此种形式使用JAVA组合(Java Composition)并且适配器包含原始对象。
Adapter Design Pattern – Class Adapter
//Using inheritance for adapter pattern
public class SocketClassAdapterImpl extends Socket implements SocketAdapter{
@Override
public Volt get120Volt() {
return getVolt();
}
@Override
public Volt get12Volt() {
Volt v= getVolt();
return convertVolt(v,10);
}
@Override
public Volt get3Volt() {
Volt v= getVolt();
return convertVolt(v,40);
}
private Volt convertVolt(Volt v, int i) {
return new Volt(v.getVolts()/i);
}
}
Adapter Design Pattern – Object Adapter Implementation
public class SocketObjectAdapterImpl implements SocketAdapter{
//Using Composition for adapter pattern
private Socket sock = new Socket();
@Override
public Volt get120Volt() {
return sock.getVolt();
}
@Override
public Volt get12Volt() {
Volt v= sock.getVolt();
return convertVolt(v,10);
}
@Override
public Volt get3Volt() {
Volt v= sock.getVolt();
return convertVolt(v,40);
}
private Volt convertVolt(Volt v, int i) {
return new Volt(v.getVolts()/i);
}
}
注意两种适配器的实现几乎相同,他们都继承了SocketAdapter接口。适配器接口也可以是个抽象类。
下面是测试代码:
public class AdapterPatternTest {
public static void main(String[] args) {
testClassAdapter();
testObjectAdapter();
}
private static void testObjectAdapter() {
SocketAdapter sockAdapter = new SocketObjectAdapterImpl();
Volt v3 = getVolt(sockAdapter,3);
Volt v12 = getVolt(sockAdapter,12);
Volt v120 = getVolt(sockAdapter,120);
System.out.println("v3 volts using Object Adapter="+v3.getVolts());
System.out.println("v12 volts using Object Adapter="+v12.getVolts());
System.out.println("v120 volts using Object Adapter="+v120.getVolts());
}
private static void testClassAdapter() {
SocketAdapter sockAdapter = new SocketClassAdapterImpl();
Volt v3 = getVolt(sockAdapter,3);
Volt v12 = getVolt(sockAdapter,12);
Volt v120 = getVolt(sockAdapter,120);
System.out.println("v3 volts using Class Adapter="+v3.getVolts());
System.out.println("v12 volts using Class Adapter="+v12.getVolts());
System.out.println("v120 volts using Class Adapter="+v120.getVolts());
}
private static Volt getVolt(SocketAdapter sockAdapter, int i) {
switch (i){
case 3: return sockAdapter.get3Volt();
case 12: return sockAdapter.get12Volt();
case 120: return sockAdapter.get120Volt();
default: return sockAdapter.get120Volt();
}
}
}
测试代码的输出结果是:
v3 volts using Class Adapter=3
v12 volts using Class Adapter=12
v120 volts using Class Adapter=120
v3 volts using Object Adapter=3
v12 volts using Object Adapter=12
v120 volts using Object Adapter=120
Adapter Design Pattern Example in JDK
在JDK中可以很容易找出几个简单的适配器模式的应用
java.util.Arrays#asList()
java.io.InputStreamReader(InputStream) (returns a Reader)
java.io.OutputStreamWriter(OutputStream) (returns a Writer)
使用场景
- 系统需要使用现有的类,而这些类的接口不符合系统的需要。
- 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
- 需要一个统一的输出接口,而输入端的类型不可预知。
网友评论