前面三篇文章分别学习了单例模式、三种工厂模式和建造者模式,它们都是比较经常使用的建立型模式,顾名思义就是建立对象的。从这篇文章开始来学习结构型设计模式,今天是第一篇——适配器模式。java
首先拿我使用的小米手机为例,它撤销了原来的 Audio 接口,要使用耳机听歌呢,就必须使用 Type-C to Audio 转接线(以下图),一头接上手机,一头接上耳机线。(ps:话说,每次听歌和充电都要换来换去的,好麻烦)设计模式
其实,这就是一个实际的适配器,和设计模式中的适配器扮演着一样的角色,将一个接口转换为另外一个接口,以符合用户的指望。ide
下面咱们就将这个例子转换为代码,看它是如何实现的。之前的手机呢,有两个接口,使用 TypeC 接口充电:post
public interface TypeCInterface {
// 充电
void chargeWithTypeC();
}
public class TypeCInterfaceImpl implements TypeCInterface {
@Override
public void chargeWithTypeC() {
System.out.println("使用 Type-C 接口充电");
}
}
复制代码
使用 Audio 接口听歌:学习
public interface AudioInterface {
// 听歌
void listenWithAudio();
}
public class AudioInterfaceImpl implements AudioInterface {
@Override
public void listenWithAudio() {
System.out.println("使用 Audio 接口听歌");
}
}
复制代码
而咱们的手机,同时有这两个接口,用来充电和听歌:this
public class XiaomiPhone {
private AudioInterface audioInterface;
private TypeCInterface typeCInterface;
public XiaomiPhone(AudioInterface audioInterface, TypeCInterface typeCInterface) {
this.audioInterface = audioInterface;
this.typeCInterface = typeCInterface;
}
public void charge() {
typeCInterface.chargeWithTypeC();
}
public void listen() {
audioInterface.listenWithAudio();
}
}
复制代码
而咱们就能够用手机来边充电,边听歌了:spa
public class Client {
public static void main(String[] args) {
AudioInterface audioInterface = new AudioInterfaceImpl();
TypeCInterface typeCInterface = new TypeCInterfaceImpl();
XiaomiPhone xiaomiPhone = new XiaomiPhone(audioInterface, typeCInterface);
xiaomiPhone.charge();
xiaomiPhone.listen();
}
}
复制代码
原本这一切都好好的,但是小米手机把 Audio 接口取消了,咱们无法直接使用来听歌了。因而,咱们只好使用转接线,将 Type-C 接口转为 Audio 接口:设计
// 需将其转换为 Audio 接口,因此实现了 AudioInterface
public class TypeCToAudioTieline implements AudioInterface {
private TypeCInterface typeCInterface;
// 另外一头是 TypeC,因此传入 TypeCInterface
public TypeCToAudioTieline(TypeCInterface typeCInterface) {
this.typeCInterface = typeCInterface;
}
@Override
public void listenWithAudio() {
// ···
typeCInterface.chargeWithTypeC();
}
}
复制代码
而后呢,把转接线插入到手机上(把手机和转接线看做一个总体,它只有 Audio 接口了):code
public class XiaomiPhone {
private AudioInterface audioInterface;
public XiaomiPhone(AudioInterface audioInterface) {
this.audioInterface = audioInterface;
}
public void listenWithAudio() {
audioInterface.listenWithAudio();
}
}
复制代码
因而,如今咱们就经过转接线,将 Type-C 接口转换成了 Audio 接口。而后将耳机插在转接线上,就能够听歌了:cdn
public class Client {
public static void main(String[] args) {
TypeCInterface typeCInterface = new TypeCInterfaceImpl();
TypeCToAudioTieline tieline = new TypeCToAudioTieline(typeCInterface);
XiaomiPhone xiaomiPhone = new XiaomiPhone(tieline);
xiaomiPhone.listenWithAudio();
}
}
复制代码
上述模式就是适配器模式,它将一个类的接口转换成用户所须要的另外一个接口,使得本来接口不兼容的类能够一块儿工做。
它的 UML 图以下:
下面咱们来总结适配器模式的优势:
缺点:
经过 InputStreamReader,能够将 InputStream 字节流转换为字符流进行处理。
public class InputStreamReader extends Reader {
private final StreamDecoder sd;
// 将 inputStream 转换为 InputStreamReader
public InputStreamReader(InputStream in) {
super(in);
try {
sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
} catch (UnsupportedEncodingException e) {
throw new Error(e);
}
}
public int read() throws IOException {
return sd.read();
}
}
复制代码
另外,好比在 Spring AOP 中,将 Advice 封装成对应的拦截器类型。或是在 Spring MVC 中,经过适配器模式,用于执行目标 Controller 中的请求处理方法。
因为对其源码不太熟悉,这里也就不详细说了。感兴趣的小伙伴能够看看这篇文章。