一.定义
使原本不能兼容的接口或类经过适配器可以进行使用。
二.结构
目标接口:无法直接访问但所需要使用的接口,即进行适配后可以使用的接口
适配者类:当前可以被访问的接口
适配器类:是一个转换器,通过继承或引用适配者对象,把适配者接口转换成目标接口,使用户可以通过访问适配者类的方法访问目标接口。
三.案例引入
电脑一半只有Type_A接口,但有时需要读取SD卡,此时就需要一个SD适配器,其一端是Type_A接口,另一端是SD卡的接口。
代码实现:
Type_A接口及其实现
/**
* Type_A的接口
*/
public interface TypeA_Interface {
String read();
void write();
}
/**
* U盘
*/
public class TypeA implements TypeA_Interface{
@Override
public String read() {
System.out.println("读取TypeA");
return null;
}
@Override
public void write() {
System.out.println("写入TypeA");
}
}
SD卡接口及其实现
/**
* SD卡的接口
*/
public interface SD_Interface {
String read();
void write();
}
/**
* 某SD卡
*/
public class SD implements SD_Interface{
@Override
public String read() {
System.out.println("读取SD卡");
return null;
}
@Override
public void write() {
System.out.println("写入SD卡");
}
}
SD卡适配器
/**
* SD适配器,其有Type_A接口,也有SD卡的接口
*/
public class SD_Adapter implements TypeA_Interface{
private SD_Interface sd_interface;
public SD_Adapter(SD_Interface sd_interface) {
this.sd_interface = sd_interface;
}
@Override
public String read() {
return sd_interface.read();
}
@Override
public void write() {
sd_interface.write();
}
}
电脑
/**
* 电脑,有Type_A接口
*/
public class Computer implements TypeA_Interface{
private TypeA_Interface typeA_interface;
public Computer(TypeA_Interface typeA_interface) {
this.typeA_interface = typeA_interface;
}
@Override
public String read() {
return typeA_interface.read();
}
@Override
public void write() {
typeA_interface.write();
}
}
分析
这个例子很符合适配器模式的作用。两个接口就是是use接口,各个接口的实现类是具体的东西。电脑实现了TypeA_Interface,代表它上面有Type_A的接口,可以进行读取Type_A接口的物品。但现在需要读取SC卡的信息。则定义了一个SD_Adapter类。它上面有TypeA接口,所以实现了TypeA_Interface,也有SD卡接口,所以定义了成员变量SD_Interface。当调用TypeA_Interface接口的read()方法时,适配器在内部进行了转换,调用了SD_Interface的read()方法。
简而言之,当A类想访问另一个类C类(目标类)但却无法访问时,适配器通过继承现有接口B类(适配者类,此类A类可以访问)使A类可以访问适配器类,之后重写B类的方法,在方法内访问C类,此时A类经过适配器类就能访问到C类了。
四.使用场景
使用第三方提供的组件,但组件接口定义与自己要求的接口的定义不同。
以前做好的功能被需要,但其接口与先需要接口不一致。
五.案例分析
java中转化流InputStreamReader,OutStreamWriter,就使用了适配器模式。
uml类图如下
我们需要将键盘中输入的字母转成字符形式,就需要使用字符流,但键盘打字是通过字节流,字符流无法直接访问字节流,所以就需要适配器。其中,StreamDecoder就是适配器,它实现了Reader接口,可以使用字符流读取,但现在需要使用字节流读取再转成字符流,则需要在实现的方法内调用InputStream接口的方法,从而可以使用字节流读取。经过转化,就实现了将字节流转成字符流。
相比于适配器模式,转换流就是多嵌套了一层。