意图:将一个类的接口转换成客户希望的另外一个接口。
何时使用: 1、系统需要使用现有的类,而此类的接口不符合系统的需要。 2、通过接口转换,将一个类插入另一个类系中。
如何解决:继承或依赖(推荐)。
优点:

  • 把目标类和适配者类解耦,提高扩展性
  • 符合OCP,可以在原有代码基础上增加新的适配器
  • 具体的实现封装在适配者类中,对于客户端类来说是透明的(就是客户端感受不到)

缺点: 1、过多使用会让系统非常零乱。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。 2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
使用场景:

  • 已经存在的类,它的方法和需求不匹配时(比如我们想要复用一些现有的类,它只是接口不符合,就可以用适配器模式)
  • 不是软件设计阶段去考虑的设计模式,而是随着软件维护,不同产品、不同厂家造成功能类似而接口不同情况下的解决方案。
  • 有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。

对象适配器
符合组合复用原则,使用委托机制(优先使用组合而不是继承)

适配器模式 - 图1
类适配器
通过类继承来实现

适配器模式 - 图2
适配器模式 - 图3

实现

我们有一个 MediaPlayer 接口和一个实现了 MediaPlayer 接口的实体类 AudioPlayer。默认情况下,AudioPlayer 可以播放 mp3 格式的音频文件。
我们还有另一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的实体类。该类可以播放 vlc 和 mp4 格式的文件。
我们想要让 AudioPlayer 播放其他格式的音频文件。为了实现这个功能,我们需要创建一个实现了 MediaPlayer 接口的适配器类 MediaAdapter,并使用 AdvancedMediaPlayer 对象来播放所需的格式。
AudioPlayer 使用适配器类 MediaAdapter 传递所需的音频类型,不需要知道能播放所需格式音频的实际类。AdapterPatternDemo 类使用 AudioPlayer 类来播放各种格式。
适配器模式 - 图4
image.png

双向适配器

设计和实现一个双向适配器实例,使得猫Cat可以学狗Dog叫Cry() ,狗可以学猫抓老鼠CatchMouse()
适配器模式 - 图6