适配器模式-简介
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型设计模式,它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或者不兼容的接口功能。
适配器模式分为以下两类:
- 类适配器模式(继承):耦合度较高
- 对象适配器模式(聚合--推荐):耦合度较低
举个例子:
在生活中,我们经常给手机充电,通常来说我们的手机充电头是两头插座,而某些国外的地区,墙上的插口只有三头插口,这个时候,手机的充电头两头插口和墙上的三头插口就不兼容了,这个时候我们可以使用电源适配器,电源适配器一端连接三头插口,一段连接我们的手机充电头,这样我们就实现了充电功能。
为什么需要适配器模式?
将一个类的接口转换成客户所需要的另外一种接口。适配器使得原本由于不兼容而不能一起工作的哪些类可以一起工作,遵循了"开闭原则"。
适配器模式的结构组成
我们想象一下手机耳机的场景,有一根3.5mm接口的耳机,但是手机上之后Type-C的接口,以及一根TypeC耳机转接头。
- 目标接口(Target):当前业务所期待的接口,这里是TypeC接口。
- 适配者类(Adaptee):它是被访问的和适配的现存组件库中的接口,这里是 3.5mm 耳机接口。
- 适配器类(Adapter):它是一个转换器,通过继承或者引用适配者对象,把适配者接口转换成目标接口,让客户按照目标接口的格式访问适配者,这里指的是 TypeC耳机转接头。
代码示例
现在有一台电脑只能读取SD卡,而要读取TF卡中的内容就需要使用适配器模式。
类适配器模式
适配器通过继承原接口 实现新接口 的方法实现适配。
java
//SD卡的接口
public interface SDCard {
//读取SD卡方法
String readSD();
//写入SD卡功能
void writeSD(String msg);
}
//SD卡实现类
public class SDCardImpl implements SDCard {
public String readSD() {
String msg = "sd card read a msg :hello word SD";
return msg;
}
public void writeSD(String msg) {
System.out.println("sd card write msg : " + msg);
}
}
//电脑类
public class Computer {
public String readSD(SDCard sdCard) {
if(sdCard == null) {
throw new NullPointerException("sd card null");
}
return sdCard.readSD();
}
}
//TF卡接口
public interface TFCard {
//读取TF卡方法
String readTF();
//写入TF卡功能
void writeTF(String msg);
}
//TF卡实现类
public class TFCardImpl implements TFCard {
public String readTF() {
String msg ="tf card read msg : hello word tf card";
return msg;
}
public void writeTF(String msg) {
System.out.println("tf card write a msg : " + msg);
}
}
//定义适配器类(SD兼容TF)
public class SDAdapterTF extends TFCardImpl implements SDCard {
public String readSD() {
System.out.println("adapter read tf card ");
return readTF();
}
public void writeSD(String msg) {
System.out.println("adapter write tf card");
writeTF(msg);
}
}
//测试类
public class Client {
public static void main(String[] args) {
Computer computer = new Computer();
SDCard sdCard = new SDCardImpl();
System.out.println(computer.readSD(sdCard));
System.out.println("------------");
SDAdapterTF adapter = new SDAdapterTF();
System.out.println(computer.readSD(adapter));
}
}
说明:
类适配器违背了"合成复用原则"。类适配器是客户类有一个接口规范的情况下可用,反之不可用。
对象适配器模式
适配器 实现新接口 并且 聚合原接口实现类 来完成适配。
java
//创建适配器对象(SD兼容TF)
public class SDAdapterTF implements SDCard {
private TFCard tfCard;
public SDAdapterTF(TFCard tfCard) {
this.tfCard = tfCard;
}
public String readSD() {
System.out.println("adapter read tf card ");
return tfCard.readTF();
}
public void writeSD(String msg) {
System.out.println("adapter write tf card");
tfCard.writeTF(msg);
}
}
//测试类
public class Client {
public static void main(String[] args) {
Computer computer = new Computer();
SDCard sdCard = new SDCardImpl();
System.out.println(computer.readSD(sdCard));
System.out.println("------------");
TFCard tfCard = new TFCardImpl();
SDAdapterTF adapter = new SDAdapterTF(tfCard);
System.out.println(computer.readSD(adapter));
}
}
总结
优点 :
1、可以让任何两个没有关联的类一起运行。
2、提高了类的复用。
3、增加了类的透明度。
4、灵活性好。
缺点 :
1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。