1.适配器模式概述
适配器模式,就是两个原本不兼容的接口结合在一起,使得它们可以一起工作。
举例: 1、美国电器 110V,中国 220V,就要有一个适配器将 110V 转化为 220V。 2、JAVA JDK 1.1 提供了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,则要将以前系统的 Enumeration 接口转化为 Iterator 接口,这时就需要适配器模式。 3、在 LINUX 上运行 WINDOWS 程序。 4、JAVA 中的 jdbc。
适配器模式中有以下的几个角色:
- 目标(target):当前业务期待的接口,可以是抽象类
- 适配者(Adaptee):希望加入到业务环境发挥作用的接口
- 适配器(Adapter):通过继承适配者类或者持有适配者类的实现对象,完成适配。
现在考虑这样一个业务场景,Window的读卡器只能读取SD类型的卡,但是现在有一个TF类型的卡需要被读入。根据上面的角色介绍,那么可以画出如下的UML类图:
- SDCard:对应于上面的target类,SDCardImpl是它的实现类。
- TFCard:对应于上面的适配者类,想要被Computer读取。TFCardImpl是实现类。
- CardAdapter:对应适配器,实现了SDCard接口是让他先拥有target的特征,好让Computer的readCard方法能够接受其对象作为参数。继承TFCardImpl是让其拥有TFCardImpl已经实现的方法。
target一族:
public interface SDCard {
public String readCard();
public void writeCard(String text);
}
public class SDCardImpl implements SDCard{
protected String text;
@Override
public String readCard() {
return text;
}
@Override
public void writeCard(String text) {
this.text=text;
}
}
adaptee一族:
public interface TFCard {
public String readCard();
public void writeCard(String text);
}
public class TFCardImpl implements TFCard{
protected String text;
@Override
public String readCard() {
return text;
}
@Override
public void writeCard(String text) {
this.text=new String(text);
}
}
adapter:
public class CardAdapter extends TFCardImpl implements SDCard{
@Override
public String readCard() {
return super.readCard();
}
@Override
public void writeCard(String text) {
super.writeCard(text);
}
}
2.扩展
让我们回过头来思考,既然Adapter继承TFCardImpl只是希望使用它已经实现的方法,那么我们为什么不换用耦合度更低的聚合方式来达到我们的目的呢?这时候,UML图是这样的。
public class CardAdapter implements SDCard{
private TFCardImpl tfCard;
public CardAdapter(TFCardImpl tfCard){
this.tfCard=tfCard;
}
public String readCard() {
return tfCard.readCard();
}
@Override
public void writeCard(String text) {
tfCard.writeCard(text);
}
}
另外,当我们不希望实现一个类的全部接口时,可以定义一个Adapter类,给出该接口方法的默认实现。我们直接继承Adapter并直接重写我们需要的方法就好了,java中特别是在swing这块,不想重写所有的事件,就有WindowAdapter等等