目录
1.适配器模式定义
2.优点
3.缺陷
5.工作流程
6.示例
7.代码练习
8.应用场景
9.本质
10.涉及的设计原则
11.相关设计模式
12.开源框架中的应用
适配器模式定义
将一个类的接口, 转换成期望的另一个接口。(对象适配器使用组合, 类适配器使用多重继承)
优点
-
解耦性:适配器模式可以将客户端与适配者解耦,客户端只需要面对目标接口。
-
复用性:适配器可以复用已有的适配者类,而不需要修改它们的代码。
-
灵活性:通过适配器,可以在不改变现有代码的情况下引入新的适配者类。
缺陷
-
过多的适配器类:如果系统中存在大量不兼容的接口,可能会导致需要创建大量的适配器类,使代码复杂化。
-
增加复杂性:适配器模式引入了额外的类和层次结构,增加了系统的复杂性。
适配器模式结构说明
-
目标接口(Target):客户端所期望的接口,它定义了客户端可以调用的方法。
-
适配者类(Adaptee):需要被适配的类,它拥有客户端不兼容的接口。
-
适配器(Adapter):适配器类实现了目标接口,并包含一个适配者类的实例,通过适配器将客户端的请求转发给适配者。
工作流程
-
客户端通过目标接口调用适配器的方法。
-
适配器的方法内部将客户端的请求转发给适配者类。
-
适配者类执行实际的操作,并将结果返回给适配器。
-
适配器将结果返回给客户端,客户端无需了解适配者的具体实现。
示例
场景说明:手机听筒从圆的TRS插孔转变成扁的TypeC插孔后,圆头的的耳机需要接一个适配器才能听歌。类似的还有笔记本扩展坞接投影仪、圆孔插头的耳麦接转接头连电脑主机USB插孔。(直接造TypeC接口的耳机线成本不高,让厂商接受标准把hdmi接口的投影仪改成USB接口可能他更愿意送你一根转接线。。。)
代码练习
1.创建目标接口EarPhone,提供一个TypeCMusic()方法:
// 目标接口 - typeC接口耳机听听歌
public interface EarPhone {
void TypeCMusic();
}
2.创建适配者TrsTelPhone,拥有一个TrsMusic()方法:
// 适配者 - Trs接口的手机
public class TrsTelPhone {
void TrsMusic() {
System.out.println("Trs听筒接口手机听音乐...");
}
}
3.需要一个适配器EarPhoneAdapter通过适配者实现目标接口:
// 适配器 - 耳机转接头
public class EarPhoneAdapter extends TrsTelPhone implements EarPhone{
@Override
public void TypeCMusic() {
this.TrsMusic();
}
}
4.客户端用TypeC的耳机线在Trs接口的手机上听听歌:
// 客户端 - 用TypeC的耳机线在Trs接口的手机上听听歌
public class Client {
public static void main(String[] args) {
EarPhone earPhone = new EarPhoneAdapter();
earPhone.TypeCMusic();
}
}
应用场景
-
当需要将一个已经存在的类与另一个不兼容的接口进行协作时,可以使用适配器模式。
-
当希望复用一个类,但它的接口与系统的其他部分不兼容时,可以使用适配器模式。
-
当需要创建一个可以与多个不同接口交互的类时,适配器模式可以帮助将这些接口统一起来。
本质
适配器模式的本质是将一个类的接口转换成客户端所期望的接口,以满足客户端的需求。
涉及的设计原则
- 开闭原则(Open/Closed Principle):适配器模式允许在不修改现有代码的情况下引入新的适配者类,符合开闭原则。
相关设计模式
- 外观模式(Facade Pattern):外观模式提供了一个简化的接口,而适配器模式用于将一个接口转换成另一个接口。它们都可以用于简化客户端与系统的交互。
开源框架中的应用
一个示例是在 Java 的 java.util.Arrays
类中,提供了一个 asList
方法,该方法将数组转换成列表。这是一个适配器模式的应用,它允许客户端使用列表操作数组,而无需了解列表和数组的具体实现细节。
String[] array = {"apple", "banana", "cherry"};
List<String> list = Arrays.asList(array);
// Now, you can use list operations on the array:
list.add("date"); // This is allowed because of the adapter