本文已参加【新人创作礼】活动,一起开启掘金创作之路。
概念
适配器模式(Adapter Pattern)又叫做变压器模式,变压器把一种电压变换为另一种电压。将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。[1,2]
- 角色 目标(Target)角色:该角色定义要转换成的目标接口。
源(Adaptee)角色:需要被转换成目标角色的源角色。
适配器(Adapter)角色:该角色是适配器模式的核心,其职责是通过继承或是类关联的方式,将源角色转换为目标角色。
对象适配器
在对象适配器模式中,适配器与适配者之间是关联关系(使用频率更高)
class Adapter extends Target {
// 适配者
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
public void request() {
// 适配者方法
adaptee.specificRequest();
}
}
类适配器
在类适配器模式中,适配器与适配者之间是继承(或实现)关系
class Adapter extends Adaptee implements Target {
public void request() {
// 适配者方法
super.specificRequest();
}
}
双向适配器
在双向适配器中,适配者可以通过适配器调用目标类的方法,目标类也可以通过适配器调用适配者的方法。
class Adapter implements Adaptee, Target {
// 适配者
private Adaptee adaptee;
// 目标类
private Target target;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
public Adapter(Target target) {
this.target = target;
}
public void request() {
// 适配者方法
adaptee.specificRequest();
}
public void specificRequest() {
target.request();
}
}
缺省适配器
缺省适配器模式(Default Adapter Pattern):当不需要实现一个接口所提供的所有方法时,可先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求。它适用于不想使用一个接口中的所有方法的情况,又称为单接口适配器模式。
- 角色 (1)ServiceInterface(适配者接口):它是一个接口,通常在该接口中声明了大量的方法。
(2)AbstractServiceClass(缺省适配器类):使用空方法的形式实现了在ServiceInterface接口中声明的方法。通常将它定义为抽象类。
(3)ConcreteServiceClass(具体业务类):它是缺省适配器类的子类,在没有引入适配器之前,它需要实现适配者接口,因此需要实现在适配者接口中定义的所有方法,而对于一些无须使用的方法也不得不提供空实现。在有了缺省适配器模式之后,可以直接继承该适配器类,根据需要有选择性地覆盖在适配器类中定义的方法。
总结
优点
- 目标类和适配器类解耦,不用修改原有结构
- 增加类的透明性和复用性。具体业务逻辑封装在适配者类中,一个适配者类可以在不同系统中复用
缺点
- 对于Java这类不支持多重继承的语言,一次只能适配一个适配者
- 适配者不能是最终类,例如在Java中不能为final类(final类不能被继承)
参考资料
[1] 刘伟. 设计模式的艺术[M]. 清华大学出版社, 2020.
[2] 青岛东合信息技术有限公司. 设计模式:Java 版[M]. 电子工业出版社, 2012.