这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战
概述
适配器(Adapter Pattern)是通过一个适配类,将一个类的行为转换为另一种形式,这个适配类又称为包装器,因此适配器模式又被称为包装器(Wrapper Pattern)。适配器模式既可以是类结构型模式,也可以是对象结构型模式。
在适配器模式中引入了一个被称为适配器(Adapter)的包装类,它所包装的源对象称为适配者(Adaptee),适配器所返回的行为就是目标(Target)。例如:张三开了一家水壶制造厂,水壶需要打孔,目前的机器只能打直径一厘米的孔,现在客户需要直径三厘米的孔,张三不想再买一台三厘米的机器,同时机器的钻头不能更换,因此张三将直径三厘米的钻头套在直径一厘米的钻头上,这个动作就是适配器,直径一厘米的钻头就是适配者,直径三厘米的钻头目标。
结构
- 对象适配器模式。在该模式下,适配器与适配者之间是关联关系。
- 类适配器模式。在该模式下,适配器与适配者之间是继承关系。
- 缺省适配器模式。缺省适配器模式(Default Adapter Pattern)又称为单接口适配器模式,是类适配器模式的变体,当不需要实现一个接口所提供的所有方法时,可先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现,那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求。
- Target(目标类):目标类是客户所需要的接口,可以是一个抽象类和接口,也可以是具体类。
- Adapter(适配器类):适配器类是适配器模式的核心,它将 Adaptee 和 Target 进行适配。
- Adaptee(适配者类):适配者是被适配的角色,它是已存在且无法被修改的,因此需要被适配,一般无法获取该类的源代码。
优点
- 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构。
- 提高了类的复用度,适配者在原有的系统中可以正常使用,在目标类中可以充当新的角色。
- 扩展性强,可以通过配置文件很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器,符合开闭原则。
对象适配器模式还有如下优点:
- 一个对象适配器可以把多个不同的适配者适配到同一个目标。
- 由于适配器和适配者之间是关联关系,因此可以适配一个适配者的子类,符合里氏代换原则。
缺点
- Java 不支持多继承,一个适配器只能适配一个适配者。
- 适配者类不能为最终类。
- 类适配器模式中的目标类只能为接口,不能为类。
对象适配器模式的缺点如下:
- 当需要置换适配者类的某些方法时,需要把适配者的子类当做真正的适配者,实现过程较为复杂。
应用场景
- 当一个接口已经投产或者无法获取该接口的源码,并且该接口无法满足现有需求时,就可以使用适配器模式。
- 想创建一个可以重复使用的类,并且这些类彼此之间没有太大的关联。
JDK 中的应用
在 JDK 中大量使用了适配器模式,特别是在 IO 中,如:java.io.InputStreamReader
、java.io.StringReader
、java.io.OutputStreamWriter
、java.io.ByteArrayInputStream
等。
java.io.InputStreamReader
是一个适配器,java.io.Reader
是适配者,java.io.InputStream
是目标;ByteArrayInputStream 和 OutputStreamWriter 同理。
java.io.StringReader
是适配器,java.io.Reader
是适配者,java.lang.String
是目标。