Java 设计模式之适配器模式
一、简介
定义:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
主要角色:
目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
二、 类结构型模式
通过适配器以及上面的定义我们可以知道,适配器模式就是为了适配或兼容当前已有的类,因为我们原本的接口不兼容所导致类之间无法一起工作,适配器就是为了解决这一点,为了更好理解,我们先看未使用适配器模式之前的代码。
举例:当前有一台电脑,可以读取和写入SD卡,先看代码实现。
目标接口:
public interface SdCard { //读取Sd卡的数据 String readSdCard(); //写入Sd卡的数据 void writeSdData(String data); }
实现类:
public class SdCardImpl implements SdCard{ @Override public String readSdCard() { return "我是Sd卡中的数据"; } @Override public void writeSdData(String data) { System.out.println("往Sd卡中写入了数据:"+data); } }
电脑类:
public class Computer { private SdCard sdCard; public Computer(SdCard sdCard){ this.sdCard = sdCard; } //读取数据 public String readData(){ return sdCard.readSdCard(); } //写入数据 public void writrData(String data){ sdCard.writeSdData(data); } }
使用:
Computer computer = new Computer(new SdCardImpl()); //读取数据 String data = computer.readData(); System.out.println(data); //写入数据 computer.writrData("我是数据");
输出:
我是Sd卡中的数据 往Sd卡中写入了数据:我是数据
此时使用电脑读取和写入Sd卡中的数据就完成了。那么此时需求来了,我又想用电脑读取Tf卡中的数据,又不能修改现有的代码怎么办?接下来就要用适配器模式,来看代码:
适配者类(Tf):
public interface TfCard { //读取Tf卡的数据 String readTfCard(); //写入Tf卡的数据 void writeTfData(String data); } public class TfCardImpl implements TfCard{ @Override public String readTfCard() { return "我是Tf卡中的数据"; } @Override public void writeTfData(String data) { System.out.println("往Tf卡中写入了数据:"+data); } }
适配器类:
//实现SdCard //继承TfCard实现类 public class SdAdapterTf extends TfCardImpl implements SdCard{ @Override public String readSdCard() { return readTfCard(); } @Override public void writeSdData(String data) { writeTfData(data); } }
使用:
public static void main(String[] args) { Computer computer1 = new Computer(new SdAdapterTf()); //读取数据 String data1 = computer1.readData(); System.out.println(data1); //写入数据 computer1.writrData("我是数据"); }
输出:
我是Tf卡中的数据 往Tf卡中写入了数据:我是数据
至此类结构型适配器已经完成了,简单理解就是说 我们为现有类提供了一个适配器类(SdAdapterTf),通过实现目标类的接口,实现里面的读写方法,并继承适配者类和调用适配者的读写方法完成了适配,是通过new Computer传入适配器,Computer构造方法接收SdCard的参数,因为适配器实现了SdCard,并调用适配者的方法,因为适配器也继承自TfCard,从而达到适配的效果。
由此补充一点:只有当业务中存在一个接口规范的情况下才可以用。
三、对象结构型模式
对象结构型相比上面的类结构型只有适配器类(SdAdapterTf)发生了改变,类结构型采用继承的模式实现,而对象结构型采用聚合的模式实现。
适配器类:
//实现SdCard //持有TfCard public class SdAdapterTf implements SdCard { private TfCard tfCard; public SdAdapterTf(TfCard tfCard){ this.tfCard = tfCard; } @Override public String readSdCard() { return tfCard.readTfCard(); } @Override public void writeSdData(String data) { tfCard.writeTfData(data); } }
使用:
public static void main(String[] args) { TfCardImpl tfCard = new TfCardImpl(); SdAdapterTf sdAdapterTf = new SdAdapterTf(tfCard); Computer computer = new Computer(sdAdapterTf); //读取数据 String data = computer.readData(); System.out.println(data); //写入数据 computer.writrData("我是数据"); }
输出:
我是Tf卡中的数据 往Tf卡中写入了数据:我是数据 关于适配器模式的应用场景:
之前开发的系统与现在新功能的接口不一致;
第三方sdk中的接口和自己要求的接口定义不同时。