适配器设计模式是结构设计模式之一,它的使用使得两个不相关的接口可以一起工作。连接这些不相关接口的对象称为适配器。
一. 介绍
适配器设计模式在现实生活中很常见,比如我最近白嫖了一个老旧的显示屏,不过他是VGA接口,可是我的笔记本支持HDMI**,没有支持VGA接口,那么就是要一个转接头将他们连接起来,这个转接头就是本文说的**适配器
适配器设计模式是一种结构型设计模式,它允许接口不兼容的对象能够相互合作。适配器模式通常用于将一个类的接口转换为客户端期望的另一个接口。这种模式通常用于解决接口不兼容的问题。
适配器模式包含以下主要角色:
- 目标(Target)接口:这是当前系统业务所期待的接口,它可以是抽象类或接口。客户端通过这个接口与适配器进行交互。
- 适配者(Adaptee)类:这是被访问和适配的现存组件库中的组件接口。适配器通过这个接口与适配者进行交互。
- 适配器(Adapter)类:这是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。适配器实现了目标接口,并持有一个适配者的实例。当客户端通过目标接口调用适配器的方法时,适配器会委托适配者的实例来完成实际的操作。
二. 代码案例讲解
2.1 定义具体事物
以我那个显示屏为例子,首先我们的目的是通过转接头使我们的笔记本能够连接上VGA的显示器,我们现在笔记本只能支持hdmi连接,所以我们先定义一个抽象的接口类型类,实现Hdmi和Vga接口,在定义显示屏,和笔记本类
/**
* @author chenyunzhi
* @date 2024/3/5 21:45
*/
public interface InterfaceType {
/**
* 接口类型
* @return 返回类型
*/
public String type();
}
/**
* hdmi接口
*
* @author chenyunzhi
* @date 2024/3/5 21:42
*/
public class InterfaceHdmi implements InterfaceType{
@Override
public String type() {
return "HDMI";
}
}
/**
* vga接口
* @author chenyunzhi
* @date 2024/3/5 21:44
*/
public class InterfaceVga implements InterfaceType{
@Override
public String type() {
return "VGA";
}
}
然后在写一个VGA接口的显示屏和笔记本类
/**
* 只有VGA接口的显示屏
*
* @author chenyunzhi
* @date 2024/3/5 21:48
*/
public class Display {
public InterfaceVga getInterfaceType() {
return new InterfaceVga();
}
}
/**
* 只能连接hdmi的笔记本
*
* @author chenyunzhi
* @date 2024/3/4 22:49
*/
public class Laptop {
public void connect(InterfaceHdmi hdmi) {
System.out.println("笔记本" + hdmi.type() + "连接成功");
}
}
2.2 定义适配器
在实现适配器模式时,有两种方法 - 类适配器和对象适配器 - 但是这两种方法都会产生相同的结果。
- 类适配器- 这种形式使用java 继承并扩展源接口。
- 对象适配器- 这种形式使用Java 组合,并且适配器包含源对象。
2.2.1 类适配器
然后我们定义一个HDMI到VGA的适配器
/**
* 类适配器接口实现
*
* @author chenyunzhi
* @date 2024/3/5 21:53
*/
public class InterfaceClassAdapterImpl extends Display implements InterfaceAdapter{
@Override
public InterfaceHdmi vgaAdapterHdmi() {
System.out.println("vga接口转化为Hdmi接口");
return "VGA".equals(getInterfaceType().type()) ? new InterfaceHdmi(): null;
}
}
2.2.2 对象适配器
以下是一个使用对象适配器的Java代码实现:
/**
* 对象适配器实现
*
* @author chenyunzhi
* @date 2024/3/5 22:14
*/
public class InterfaceObjectAdapterImpl implements InterfaceAdapter{
private final Display display;
public InterfaceObjectAdapterImpl(Display display) {
this.display = display;
}
@Override
public InterfaceHdmi vgaAdapterHdmi() {
System.out.println("vga接口转化为Hdmi接口");
return "VGA".equals(display.getInterfaceType().type()) ? new InterfaceHdmi(): null;
}
}
2.3 测试
/**
* 测试
*
* @author chenyunzhi
* @date 2024/3/3 22:52
*/
public class Test {
public static void main(String[] args) {
Laptop laptop = new Laptop();
System.out.println("--类适配器--");
InterfaceClassAdapterImpl interfaceAdapter = new InterfaceClassAdapterImpl();
laptop.connect(interfaceAdapter.vgaAdapterHdmi());
System.out.println("--对象适配器--");
InterfaceObjectAdapterImpl interfaceObjectAdapter = new InterfaceObjectAdapterImpl(new Display());
laptop.connect(interfaceObjectAdapter.vgaAdapterHdmi());
}
}
2.4 结构图
三. 结论
适配器设计模式允许我们将一个类的接口转换为客户端所期望的另一个接口。这在我们需要使用已有的类,但其接口与我们所需的接口不匹配时非常有用。
开源例子:Reader(字符流)、InputStream(字节流)的适配使用的是InputStreamReader。