附链
你也可以在这些平台阅读本文:
定义
将一个类的接口转换成客户端期望的另一个接口。
适配器模式可以使原本接口不兼容的类可以一起工作。
两种模式
适配器模式有两种模式:
- 对象适配器:采用组合方式进行类的委托
- 类适配器:采用继承方式
三种角色
- 目标角色(Target):客户端所期待的接口(也可以是具体类或者抽象类)。
- 源角色(Adaptee):被适配者。已经存在的需要适配的接口或类。
- 适配器(Adapter):将源接口转换成目标接口。只能是具体的类。
场景示例
笔者有一台吃灰蛮久的尼康相机。由于笔者的mbp只有Type-C接口,不能直接读取相机的内存卡。为此笔者还特地斥巨资买了个Type-C的扩展坞。
这里Type-C扩展坞作为内存卡和笔记本之间的适配器,只要将内存卡插入Type-C扩展坞的SD卡接口中,再将扩展坞接入到笔记本的Type-C接口中,我们就可以通过笔记本来读取内存卡中的内容。
也就是说扩展坞将笔记本的Type-C接口适配成SD卡接口。这样理解的话,SD卡接口即为我们的目标角色,Type-C接口为被适配者(即源角色),扩展坞为两者之间的适配器。
类适配器
这里先用类适配器的方式来实现下。
创建源角色
上述已经分析了,Type-C接口作为我们的源角色,代码如下:
/**
* @author zhh
* @description TypeC接口类
* @date 2020-02-14 16:33
*/
public class TypeCInterface {
/**
* type-C读取
*/
public void typeCRead() {
System.out.println("Type-C接口读取...");
}
}
创建目标角色
创建目标角色,也就是SD卡接口。
/**
* @author zhh
* @description SD卡接口
* @date 2020-02-14 16:36
*/
public interface SDInterface {
void sdRead();
}
创建适配器
这里的适配器即Typc-C扩展坞,继承源角色,实现目标接口。
/**
* @author zhh
* @description Type-C扩展坞
* @date 2020-02-14 16:43
*/
public class TypeCDockStation extends TypeCInterface implements SDInterface {
public void sdRead() {
System.out.println("SD卡接口读取...");
System.out.println("扩展坞转换");
super.typeCRead();
}
}
测试类及输出
/**
* @author zhh
* @description 测试类
* @date 2020-02-14 16:59
*/
public class Test {
public static void main(String[] args) {
SDInterface sdInterface = new TypeCDockStation();
sdInterface.sdRead();
}
}
测试类的输出结果如下:
SD卡接口读取…
扩展坞转换
Type-C接口读取…
类结构图
以上示例类的结构图如下所示
对象适配器
再来讲讲对象适配器方式的实现。
该方式中,目标角色和源角色并未发生改动,和上述类适配器方式中保持一致,这里就不做过多的代码粘贴了。
主要变化的是适配器类。
创建适配器
/**
* @author zhh
* @description
* @date 2020-02-14 17:23
*/
public class TypeCDockStation implements SDInterface {
private TypeCInterface typeCInterface;
public TypeCDockStation(TypeCInterface typeCInterface) {
this.typeCInterface = typeCInterface;
}
public void sdRead() {
System.out.println("SD卡接口读取...");
System.out.println("扩展坞转换");
typeCInterface.typeCRead();
}
}
测试类及输出
/**
* @author zhh
* @description 测试类
* @date 2020-02-14 16:59
*/
public class Test {
public static void main(String[] args) {
TypeCInterface typeCInterface = new TypeCInterface();
SDInterface sdInterface = new TypeCDockStation(typeCInterface);
sdInterface.sdRead();
}
}
测试类的输出结果如下:
SD卡接口读取…
扩展坞转换
Type-C接口读取…
类结构图
以上示例类的结构图如下所示
总结
适用场景
- 想使用一个已存在的类,但是该类的方法不符合接口需求。
- 软件维护过程中,解决不同产品或者厂家功能类似而接口不同的情况。
优点
- 提高类的透明性
- 复用现有的类
- 目标类和适配器类解耦,提高扩展性
缺点
- 增加系统的复杂性
- 增加系统代码可读难度
参考
- 《Head First 设计模式》
- 《大话设计模式》
- 维基百科-适配器模式
- 菜鸟教程-适配器模式