一、定义:
适配器模式即是将某个类的接口转换成客户端期望的另一个接口,使原本接口不匹配的两个类能一起正常工作,目的就是消除由于接口不匹配所造成的类的兼容性。一般来说,接口不兼容的类一般具有相类似的功能。比较直白的做法是通过修改类的接口来解决接口不兼容的问题。但是,一来修改接口这种方案是不符合设计模式的“开闭原则”(Open Close Principle)的,即“对扩展开放,对修改关闭”,修改接口会影响实现接口的所有的类,这无疑会使代码维护变得复杂;二来如果我们不知道待修改的接口源码或者无法修改接口源码,那这个时候我们就要想其他的办法了。适配器模式就是为了解决这种情况而生的。
二、适配器模式的组成:
目标,客户端,被适配者,适配器
目标(Target):一个客户端需要使用的特定接口
客户端(Client):客户端需要使用目标接口,来完成某项工作
被适配者(Adaptee):需要适配的一个接口
适配器(Adapter):将被适配者的接口转化为目标的接口。
三、适配器模式的分类:
总体分为两类:类的适配器模式、对象的适配器模式。
首先,我们来看看类的适配器模式:
3.1 按照惯例上一个类的适配器模式的类关系图:
3.2 照惯例上一个实例:
以给手机充电为例
3.2.1 ChargerUsing5V接口(给手机充电,即Target)
package designpatterns.adapter;
/**
* Created by Olive on 2017/11/29.
* ChargerUsing5V就是目标接口,手机只能使用5V电压充电
*/
public interface ChargerUsing5V {
void charge();
}
3.2.2 Voltage220V类(电源类,即Adaptee)
package designpatterns.adapter;
/**
* Created by Olive on 2017/11/29.
* 待适配者
*/
public class Voltage220V {
public void charge(){
System.out.println("You are charging through 220V");
}
}
3.2.3 PowerAdapter类(电源适配器,即Adapter)
package designpatterns.adapter;
/**
* Created by Olive on 2017/11/29.
*/
public class PowerAdapter extends Voltage220V implements ChargerUsing5V {
// 调用基类的charge方法,实际使用的还是110V电压
// 适配器方法使220V电气设备可以使用110V电压
@Override
public void charge() {
super.charge();
}
}
3.2.4 PhoneClient类(拿适配器给手机充电,即Client)
package designpatterns.adapter;
/**
* Created by Olive on 2017/11/29.
*/
public class PhoneClient {
public static void main(String[] args){
ChargerUsing5V device = new PowerAdapter();
device.charge();
// ChargerUsing5V deviceObject = new PowerObjectAdapter();
// deviceObject.charge();
}
}
3.2.5 输出结果
You are charging through 220V
Process finished with exit code 0
然后,我们来看看对象的适配器模式:
3.3 给出一个对象的适配器模式的类关系图:
3.4 基于上述实例的一个修改:
3.4.1 PowerObjectAdapter类(电源适配器,即对象适配器模式下的Adapter)
package designpatterns.adapter;
/**
* Created by Olive on 2017/11/30.
*/
public class PowerObjectAdapter implements ChargerUsing5V{
Voltage220V voltage = new Voltage220V();
public void charge() {
voltage.charge();
}
}
3.4.2 PhoneClient类(拿适配器给手机充电,即Client)
package designpatterns.adapter;
/**
* Created by Olive on 2017/11/29.
*/
public class PhoneClient {
public static void main(String[] args){
// ChargerUsing5V device = new PowerAdapter();
// device.charge();
ChargerUsing5V deviceObject = new PowerObjectAdapter();
deviceObject.charge();
}
}
3.4.3 输出结果
You are charging through 220V
Process finished with exit code 0
四、 一点小总结:
从代码和类图中可以看到类的适配器和对象的适配器的客户端代码完全一致。类的适配器模式是通过继承待适配类实现的,当客户端调用适配器方法时,其方法内部调用了基类的方法;对象适配器内部持有了一个待适配类的引用,当客户端调用对象适配器方法时,其内部通过调用待适配者的实例来调用其方法。