您的位置:首页 > 其它

浅学设计模式之适配器<Adapter>模式

2012-05-26 23:06 309 查看
    适配器模式(adapter pattern)有时候也称包装样式或者包装。将一个的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类工作在一起,做法是将类别自己的接口包裹在一个已存在的类中。有两类适配器模式:·对象适配器模式 - 在这种适配器模式中,适配器容纳一个它我包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。·类适配器模式 - 这种适配器模式下,适配器继承自已实现的类(一般多重继承)。      下面我们可以看下类图:



    下面开始一个小例子。假如你朋友从日本给你带来一个日本原装相机,只能使用110V的电压充电,你在国内想使用的话必须使用一个电压转换器把国内的220V电压转换成110V电压。如下图


220V的电压转换成110V给客户。      开始代码:客户类:相机public class Camera {
public void charging(String strVoltage) {
if (strVoltage.equalsIgnoreCase("110V")) {
System.out.println("can charge");
} else {
System.out.println("the Voltage is not in conformity with the Camera");
}
}
}

这里只简单的实现了它的充电功能!被适配者:220V中国电压public class ChinaVoltage {
String getVoltage(){
System.out.println("中国电压是220V");
return "220V";
};
}

适配者:110Vpublic class JapanVoltage {
private String strVoltage = "110V";
public String getVoltage() {
System.out.println("Japan Voltage is 110V");
return strVoltage;
}
}

这里没有定义接口,直接使用了实体类!适配器:public class VoltageAdapter extends ChinaVoltage{
private JapanVoltage japanVoltage;

public void setJapanVoltage(JapanVoltage japanVoltage) {
this.japanVoltage = japanVoltage;
}

@Override
public String getVoltage() {
// TODO Auto-generated method stub
return japanVoltage.getVoltage();
}

}
测试用例:public static void main(String[] args) {
//得到相机
Camera camera =new Camera();
//得到日本电压和转换器
JapanVoltage japanVoltage = new JapanVoltage();
VoltageAdapter voltageAdapter = new VoltageAdapter();
//转换成日本电压
voltageAdapter.setJapanVoltage(japanVoltage);
//充电
camera.charging(voltageAdapter.getVoltage());

//直接用中国电压充电
camera.charging(new ChinaVoltage().getVoltage());
}
测试结果:Japan Voltage is 110V
can charge
中国电压是220V
the Voltage is not in conformity with the Camera

在这里使用的是对象适配器模式,在java中不支持多重继承,所以基本上没办法类继承方式。但是使用接口加对象的方式试一下吧:public interface IJapanVoltage {
String getJapanVoltage();
}

适配器:

public class VoltageAdapter2 extends ChinaVoltage implements IJapanVoltage{

@Override
public String getJapanVoltage() {
getVoltage();
System.out.println("转换为日本电压为110V");
return "110V";
}

}


然后测试一下:public class Test {
public static void main(String[] args) {
//得到相机
Camera camera =new Camera();
//得到日本电压和转换器
JapanVoltage japanVoltage = new JapanVoltage();
VoltageAdapter2 voltageAdapter = new VoltageAdapter2();
//充电
camera.charging(voltageAdapter.getJapanVoltage());

//直接用中国电压充电
camera.charging(voltageAdapter.getVoltage());
}
}

测试结果:中国电压是220V
转换为日本电压为110V
can charge
中国电压是220V
the Voltage is not in conformity with the Camera

适用性:
1. 系统需要使用现有的类,而此类的接口不符合系统的需要。2. 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。这些源类不一定有很复杂的接口。3. (对对象适配器而言)在设计里,需要改变多个已有子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器,而这不太实际。 效果及优缺点:对于类适配器:1. 用一个具体的Adapter类对Adaptee和Taget进行匹配。结果是当我们想要匹配一个类以及所有它的子类时,类Adapter将不能胜任工作。2. 使得Adapter可以override(重定义) Adaptee的部分行为,因为Adapter是Adaptee的一个子类。对于对象适配器:1. 允许一个Adapter与多个Adaptee,即Adaptee本身以及它的所有子类(如果有子类的话)同时工作。Adapter也可以一次给所有的Adaptee添加功能。2. 使得override(重定义)Adaptee的行为比较困难。如果一定要override Adaptee的方法,就只好先做一个Adaptee的子类以override Adaptee的方法,然后再把这个子类当作真正的Adaptee源进行适配。

最后:本文用图是从Head.First设计模式书上截的图。想学好设计模式,可以好好看看那本书。

周末愉快。。。如果觉得还可以的话,请帮忙顶一下吧。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息