适配器模式
适配器模式:将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题。
适配器模式特点
- 适配器对象实现原有接口
- 适配器对象组合一个实现新接口的对象(这个对象也可以不实现一个接口,只是一个单纯的对象)
- 对适配器原有接口方法的调用被委托给新接口的实例的特定方法
博文推荐
角色
- 被适配者:原有接口
- 目标对象:新的接口(对象)
- 适配器:将新的接口(对象)与原有接口进行适配
案例描述
这里主要以Typec手机转接器(适配器)作为例子。市面上有很多Typec接口的手机,我们充电的话一般是Typec接口的数据线都可以给手机进行充电,但有时候Typec数据线坏了或者丢了,大部分人可能就会去购买新的Typec数据线,但也有少部分人会使用Typec数据线转接器(适配器),什么是转接器呢?看下图
像这种可以用安卓数据线通过转接器插到Typec接口型的手机进行充电。
这里的转接器可以看成适配器,而安卓数据线可以看成新目标对象(新的对象),Typec插口就相当于被适配者(原有接口)。
本例UML类图关系如下
具体代码实现如下
TypcInterface
package com.lcq.adapterpattern;
/**
* Typec接口
*/
public interface TypecInterface {
//使用typec接口充电
void typecCharge();
}
AppleDataLine(苹果数据线)
package com.lcq.adapterpattern;
/**
* 苹果数据线
*/
public class AppleDataLine {
public void appleCharge(){
System.out.println("正在使用苹果数据线充电");
}
}
AndroidDataLine(安卓数据线)
package com.lcq.adapterpattern;
/**
* 安卓数据线
*/
public class AndroidDataLine {
public void androidCharge(){
System.out.println("正在使用安卓数据线充电");
}
}
TypecDataLine(Typec数据线)
package com.lcq.adapterpattern;
/**
* Typec数据线(原生)
*/
public class TypecDateLine implements TypecInterface{
public void typecCharge(){
System.out.println("正在使用typec(原生)数据线充电");
}
}
AndroidToTypecAdapter(安卓转Typec适配器)
package com.lcq.adapterpattern;
/**
* 安卓转Typec接口适配器
*/
public class AndroidToTypecAdapter implements TypecInterface{
//安卓数据线
private AndroidDataLine androidDataLine = new AndroidDataLine();
public void typecCharge() {
androidDataLine.androidCharge();
}
}
AppleToTypecAdapter(苹果转Typec适配器)
package com.lcq.adapterpattern;
/**
* 苹果转Typec适配器
*/
public class AppleToTypecAdapter implements TypecInterface{
//安卓数据线
private AppleDataLine appleDataLine = new AppleDataLine();
public void typecCharge() {
appleDataLine.appleCharge();
}
}
Phone(含Typec接口的手机)
package com.lcq.adapterpattern;
/**
* 含Typec接口的手机
*/
public class Phone {
private TypecInterface typecInterface;
public Phone(TypecInterface typecInterface){
this.typecInterface = typecInterface;
}
public void setTypecInterface(TypecInterface typecInterface){
this.typecInterface = typecInterface;
}
public void charge(){
typecInterface.typecCharge();
}
}
测试
package com.lcq.adapterpattern;
public class Test {
public static void main(String[] args) {
//使用原生数据线(无需转接器[适配器])
Phone phone = new Phone(new TypecDateLine());
phone.charge();
System.out.println("------------------------------");
//更换安卓数据线转接器(适配器)
phone.setTypecInterface(new AndroidToTypecAdapter());
phone.charge();
System.out.println("------------------------------");
//更换苹果数据线转接器(适配器)
phone.setTypecInterface(new AppleToTypecAdapter());
phone.charge();
}
}
运行结果
小结:从测试结果我们可以看出原生Typec数据线可以不用适配器就可以直接给手机充电,现实生活中也是如此。与此同时,如果我们没有Typec数据线,而只有有苹果或者安卓数据线,我们只需更换相应的转接器(适配器)即可进行充电。这与软件工程中的开闭原则很相符,无需对原有接口(TypecInterface)进行更改,只需添加新的适配器(xxxToTypecAdapter)及新的接口或对象(xxxDataLine)。