模式意图
适配器模式的重心就是在适配器上,适配器聚合或者继承需要适配的类(以来使用新的功能),适配器再实现原先定义好的某个接口或继承抽象类,在需要传入该接口实现类的地方就可以传入适配器来实现新功能了。
模式结构
类适配器模式
电脑类是目标类,电脑只能读取SD卡,但现在有TF卡,所以需要转换器让电脑能读取TF卡。
转换器继承TF卡,可以让转换器调用父类TF卡的方法。
电脑读取SD卡是将SD卡对象传入。
转换器实现SD卡接口,那么转换器也是SD卡的子实现类了,所以也可以传入电脑类。
注意
类适配器模式必须要求客户类有接口,因为适配器要和客户类和被适配类同时产生联系但又得是单继承,只能实现一个接口和继承一个类。
public class Client { public static void main(String[] args) { Computer computer = new Computer(); computer.readSD(new SDAdapterTF()); } } //目标类 class Computer{ //从SD卡中读取数据 public String readSD(SDCard sdCard){ return sdCard.readSD(); } } //适配器类 class SDAdapterTF extends TFCardImpl implements SDCard{ @Override public String readSD() { System.out.println("adapter read tf card"); return readTF(); } @Override public void writeSD(String msg) { System.out.println("adapter write tf card"); writeTF(msg); } } interface TFCard{ //读数据 String readTF(); //写数据 void writeTF(String msg); } //适配者类 class TFCardImpl implements TFCard{ @Override public String readTF() { return "TFCard read:Hello,TFCard"; } @Override public void writeTF(String msg) { System.out.println("TFCard write:"+msg); } } interface SDCard{ //读数据 String readSD(); //写数据 void writeSD(String msg); } class SDCardImpl implements SDCard{ @Override public String readSD() { return "SDCard read:Hello,SDCard"; } @Override public void writeSD(String msg) { System.out.println("SDCard write:"+msg); } }
对象适配器模式
适配器不再继承适配者类,而是将聚合适配者类,想要电脑实现TF卡的功能,就创建TF卡的适配器(该适配器需要传入TF卡对象来创建),电脑要读卡时再传入适配器类实现读卡功能。
注意与静态代理的区别
静态代理模式中,代理类和目标类实现了同一个接口,而适配器类和适配类实现的是不同的接口
public class Client { public static void main(String[] args) { Computer computer = new Computer(); //读取SD卡 System.out.println(computer.readSD(new SDCardImpl())); //利用读取TF卡 System.out.println(computer.readSD(new SDAdapterTF(new TFCardImpl()))); } } //目标类 class Computer{ //从SD卡中读取数据 public String readSD(SDCard sdCard){ return sdCard.readSD(); } } //适配器类 class SDAdapterTF implements SDCard{ private TFCard tfCard; public SDAdapterTF(TFCard tfCard){ this.tfCard = tfCard; } @Override public String readSD() { System.out.println("adapter read tf card"); return tfCard.readTF(); } @Override public void writeSD(String msg) { System.out.println("adapter write tf card"); tfCard.writeTF(msg); } } interface TFCard{ //读数据 String readTF(); //写数据 void writeTF(String msg); } //适配者类 class TFCardImpl implements TFCard{ @Override public String readTF() { return "TFCard read:Hello,TFCard"; } @Override public void writeTF(String msg) { System.out.println("TFCard write:"+msg); } } interface SDCard{ //读数据 String readSD(); //写数据 void writeSD(String msg); } class SDCardImpl implements SDCard{ @Override public String readSD() { return "SDCard read:Hello,SDCard"; } @Override public void writeSD(String msg) { System.out.println("SDCard write:"+msg); } }
应用场景
为第三方组件创建一个适配器类,聚合第三方组件,再将该适配器实现自己要求的接口,方法中传入一个接口对象就表明能使用该接口的功能,一个接口有各种实现类就可以有各种功能,由于适配器实现的接口就是我们之前定义的接口,所以适配器也就是原先接口的另一个实现类,实现了一个新的功能。
JDK源码解析
InputStream是适配类
StreamDecoder是适配器类
Reader是目标抽象类
StreamDecoder聚合了InputStream,StreamDecoder继承了Reader抽象类
相当于适配器聚合了TF卡,并实现了SD卡的接口
凡是需要用到Reader的功能的地方,可以传入适配器也可以传入其他子类