一、概述
适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配,简单点理解就是平常所见的转接头,转换器之类的存在。
适配器模式涉及3个角色:
- 源(Adaptee):它是被访问和适配的现存组件库中的组件接口(相当于typec充电线)。
- 适配器(Adapter):通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者(相当于转接头)。
- 目标(Target):当前系统业务所期待的接口,它可以是抽象类或接口(相当于lightning充电线)。
主要有3种实现方式:类适配器、对象适配器和接口适配器。
二、优缺点
优点
客户端通过适配器可以透明地调用目标接口。 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。 在很多业务场景中符合开闭原则。
缺点
适配器编写过程需要结合业务场景全面考虑,可能会增加系统的复杂性。 增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。
三、实现方式
下面从「安卓转苹果充电」为例,场景是:我手中有一部苹果手机,但是苹果手机只能用 Lightning 充电线,我这里只有 TypeC 充电线怎么办呢?弄个转接头,将TypeC 转换成为 Lightning 就可以使用了。
类适配器
通过继承来实现适配器功能。当客户在接口中定义了他期望的行为时,我们就可以应用适配器模式,提供一个实现该接口的类,并且扩展已有的类,通过创建子类来实现适配。
源适配者类
public class TypeCAdaptee {
public void chargeAndroid(){
System.out.println("typeC Android 充电口");
}
}
目标接口类
public interface LightningTarget {
void chargeIphone();
}
适配器类
public class Adapter extends TypeCAdaptee implements LightningTarget{
@Override
public void chargeIphone() {
chargeAndroid();
}
}
客户端类
public class Clienter {
public static void main(String[] args) {
LightningTarget lightningTarget = new Adapter();
lightningTarget.chargeIphone();
}
}
对象适配器
通过组合来实现适配器功能。对象适配器”通过组合除了满足“用户期待接口”还降低了代码间的不良耦合。在工作中推荐使用“对象适配”。
源适配者类
public class TypeCAdaptee {
public void chargeAndroid(){
System.out.println("typeC Android 充电口");
}
}
目标接口类
public interface LightningTarget {
void chargeIphone();
}
适配器类
public class Adapter implements LightningTarget {
private TypeCAdaptee typeCAdaptee;
public Adapter(TypeCAdaptee typeCAdaptee){
this.typeCAdaptee = typeCAdaptee;
}
@Override
public void chargeIphone() {
typeCAdaptee.chargeAndroid();
}
}
客户端类
public class Clienter {
public static void main(String[] args) {
LightningTarget lightningTarget = new Adapter(new TypeCAdaptee());
lightningTarget.chargeIphone();
}
}
接口适配器
接口适配器模式是一种特殊的适配器模式,但这个适配器是由一个抽象类实现的,并且在抽象类中要实现目标接口中所规定的所有方法,但很多方法的实现都是“平庸”的实现,也就是说,这些方法都是空方法。而具体的子类都要继承此抽象类。
接口类
public interface A {
void a();
void b();
void c();
void d();
}
适配器类
public class Adapter implements A{
@Override
public void a() {
}
@Override
public void b() {
}
@Override
public void c() {
}
@Override
public void d() {
}
}
实现类
public class AInstance extends Adapter{
@Override
public void a() {
System.out.println("实现方法a");
}
@Override
public void b() {
System.out.println("实现方法b");
}
}
客户端类
public class Clienter {
public static void main(String[] args) {
A a = new AInstance();
a.a();
a.b();
}
}
四、应用场景
- 封装有缺陷的接口设计
- 统一多个类的接口设计,比如一个支付系统,有三种不同的支付方式,微信支付、支付宝支付、网银支付,这三种支付的实现方法都不一样,那么我们可以用适配器模式,让他们对外具有统一的方法,这样,我们在调用的时候就非常的方便。
- 兼容老版本的接口,这个在我们系统升级中经常会用到。