如何在 Java 中使用适配器设计模式
Java 中的适配器设计模式,也称为 Wrapper 模式,是另一个非常有用的 GOF 模式,它有助于弥合 Java 中两个类之间的差距。 根据四人组模式列表,适配器是一种结构模式,很像 Java 中的代理、享元、门面和装饰器模式。 顾名思义,Adapter 允许具有不同接口的两个类一起工作,而无需更改任何一方的任何代码。 我们可以将 Adapter 模式视为拼图的中心部分,它连接了两块,因为接口不同而不能直接连接。
如何在 Java 中实现适配器设计模式?
在 Java 中有两种实现适配器设计模式的方法,一种使用继承,也称为类适配器模式,另一种使用组合,也称为对象适配器模式。 在这两种情况下,最好在接口中声明与客户端交互的公共方法,我们可以将其称为目标接口。
使用目标接口将面向客户端的方法包装在适配器中的一个优点是,我们可以创建一个松散耦合的设计,我们可以在开发的后期阶段用更好的实现替换适配器。
现在你的 Class Adapter 模式扩展了原始接口,它与客户端不兼容但提供了客户端所需的功能,并且它还实现了目标接口。 现在,Adapter 实现目标方法的方式是将实际工作委托给原始类,Adapter 通过扩展它来访问原始类。
类似地,在对象适配器模式的情况下,它使用组合来重用代码,它也实现了目标接口并使用原始不兼容类的对象来完成它的所有工作。 更喜欢组合而不是继承,我建议应该坚持使用对象适配器模式。
这是适配器设计模式的 UML 图,它可以使事情更容易理解,并消除我们对该模式结构的任何疑问:
在这个例子中,Client 是一个目标接口,Wizard 是 Adaptee。 为了方便Wizard的使用,我们创建了WizardAdapter,它实现了目标接口Fighter,但是将工作委托给了Adaptee。
Java 中的适配器模式 - Map 适配器
让我们再看一个 Java 适配器模式的例子。 如果大家还记得 java.util.Map
无法自动将二维对象数组作为键值对加载到 Map 中。 我们可以创建一个适配器类来执行此操作。
有时你要解决的问题就像“我没有我想要的界面”一样简单。 GOF 设计模式列表中的两个模式,适配器和外观模式通过提供备用接口解决了这个问题。
适配器模式采用我们拥有的任何接口并生成我们需要的接口。 而 Facade 模式提供了一个更简单的接口来处理多个类或资源包。
这是我在 Java 中实现的 Adapter 模式,用于将对象的二维数组转换为键值对的 Map
实现适配器设计模式的Java程序
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String args[]) {
Integer[][] squares = {{2, 4}, {3, 9}, {4, 16}};
MapAdapter adapter = new MapAdapter(squares);
System.out.println("adapter map contains : " + adapter);
}
}
class MapAdapter extends AbstractMap {
private Map map;
public MapAdapter(Object[][] array) {
super();
map = new HashMap();
for (Object[] mapping : array) {
map.put(mapping[0], mapping[1]);
}
}
@Override
public Set entrySet() {
return map.entrySet();
}
}
我们可以看到我们的 MapAdapter
扩展了 AbstractMap 以创建一个 Map,该 Map 可以采用二维数组并从中创建一个 HashMap。
这是一个更有趣的图,它将帮助大家理解 Java 中适配器模式的意图和目的。 我们可以看到现有的系统和供应商类最初不适合,但是当我们添加适配器时,难题就解决了,两个系统都可以插入在一起。
关于 Java 适配器模式的要点
现在,让我们看看有关 Java 中的适配器模式的一些要点。 这些要点将仅向您提供为什么以及何时使用适配器设计模式,以及适配器模式在 Java 软件开发中的其他优点和缺点。
- 适配器设计模式确保了将客户端调用委托给原始类的代码可重用性,即它充当原始接口的包装器,这就是为什么它也被称为包装器模式或简称为包装器。 这实际上是使用适配器模式的主要好处。
- 适配器模式是一种通用模式,很像 Singleton、Factory 和 Decorator,你会通过代码看到很多 Adapter 模式的例子,在 Java 中使用 Adapter 模式的一个主要好处是重用代码,使得 不兼容的接口一起工作并且松散耦合,因为 Adapter 倾向于很好地封装不兼容的接口。
- 在 Java 程序中使用 Adapter 设计模式的情况之一是使用第三方库。 通过确保我们的程序使用由我们控制的适配器,而不是直接使用第三方接口和类,您可以随时用类似的、性能更好的 API 替换第三方库。 我们可以将此算作使用适配器模式的优点之一。
- 在四人组设计模式中,适配器模式与代理、门面和装饰器设计模式一起属于结构设计模式。
- 许多程序员混淆了Java中的Adapter和装饰器设计模式,它们在某种程度上是相似的,尤其是基于对象的适配器模式,但是Java中的装饰器和Adapter模式之间存在细微差别。 Adapter 只是将一个接口转换为另一个接口,而没有添加额外的功能,而 装饰器模式则将新功能添加到接口中。 请参阅有关 Java 中适配器模式和装饰器模式之间区别 来了解更多信息。
- 我们还可以使用 Java 中的适配器设计模式来转换类,例如 假设我们的客户以英里为单位进行所有计算,而我们使用的图书馆需要公里。 在这种情况下,我们可以编写一个 Adapter 类,它从客户端获取英里数,将其转换为 Kilometer 并利用外部库方法进行所有计算。 在返回结果时,它可以将 KM 转换回英里并将结果发送给客户端。
- 更喜欢基于对象的适配器设计模式而不是基于类的,因为前者使用组合来重用代码,并且比Java中基于类的适配器模式的基于继承的方法更灵活。
这就是什么是 Java 中的适配器设计模式、如何以及何时使用适配器模式以及适配器设计模式的基于类和对象的实现之间的区别。 适配器是一种非常有用的通用模式,Java 开发人员应该尽可能多地利用这种模式来编写灵活的代码。
相关文章
Do you understand JavaScript closures?
发布时间:2025/02/21 浏览次数:108 分类:JavaScript
-
The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.
Do you know about the hidden traps in variables in JavaScript?
发布时间:2025/02/21 浏览次数:178 分类:JavaScript
-
Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av
How much do you know about the Prototype Chain?
发布时间:2025/02/21 浏览次数:150 分类:JavaScript
-
The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start
如何在 JavaScript 中合并两个数组而不出现重复的情况
发布时间:2024/03/23 浏览次数:86 分类:JavaScript
-
本教程介绍了如何在 JavaScript 中合并两个数组,以及如何删除任何重复的数组。