一、概述

适配器模式(Adapter Pattern)是软件设计模式中结构型模式的一种,其核心目的在于解决接口不兼容的问题。当系统需要使用某个现有类,但其接口与客户端期望的接口不匹配时,适配器模式提供了一种优雅的解决方案,无需修改现有类的源码即可实现集成。

1.1、模式定义

适配器模式通过创建一个适配器类,将一个类的接口转换成客户端所期望的另一个接口,从而使原本由于接口不兼容而无法协同工作的类能够一起工作。

1.2、应用场景

在实际开发中,以下场景常需使用适配器模式:

  • 集成第三方库或遗留系统,其接口与当前系统设计不符。
  • 系统重构或升级过程中,新旧接口需要共存。
  • 需要复用现有功能模块,但其接口定义无法直接满足新需求。

二、案例分析

假设我们正在开发一个音乐播放器应用,系统基于 AdvancedAudioPlayer 接口进行设计:

/**
 * 目标接口
 *
 * @author LS
 * @version 1.0
 * @createDate 2025/9/6 17:59
 **/
public interface AdvancedAudioPlayer {
    void playVlc(String fileName);
    void playMp4(String fileName);
}

老系统中存在一个仅支持 MP3 格式的播放器类:

/**
 * 被适配器者
 *
 * @author LS
 * @version 1.0
 * @createDate 2025/9/6 18:01
 **/
public class OldPlayer {
    public void playMp3(String fileName) {
        System.out.println("老播放器正在播放 MP3 文件: " + fileName);
    }
}

由于 OldPlayer 类不实现 AdvancedAudioPlayer 接口,无法直接在新系统中使用。此时,适配器模式可解决此问题。

适配器实现方式

适配器模式主要有两种实现方式:类适配器与对象适配器。

2.1. 类适配器 (Class Adapter)

类适配器通过继承被适配者类并实现目标接口来完成适配。

/**
 *  类适配器
 *
 * @author LS
 * @version 1.0
 * @createDate 2025/9/6 18:05
 **/
public class ClassMp3PlayerAdapter extends OldPlayer implements AdvancedAudioPlayer {
    @Override
    public void playVlc(String fileName) {
        System.out.println("类适配器播放mp3文件:" + fileName);
        playMp3(fileName);

    }

    @Override
    public void playMp4(String fileName) {
        System.out.println("类适配器播放mp3文件:" + fileName);
        playMp3(fileName);
    }
}

优点: 实现简洁。

缺点: 依赖继承,受限于 Java 的单继承机制;若被适配者已继承其他类,则无法使用;耦合度较高。

2.2. 对象适配器 (Object Adapter)

对象适配器通过组合(Composition)的方式,将被适配者作为适配器的成员变量,是更推荐的实现方式

/**
 * 对象适配器
 *
 * @author LS
 * @version 1.0
 * @createDate 2025/9/6 18:09
 **/
public class ObjectMp3PlayerAdapter implements AdvancedAudioPlayer {

    private OldPlayer oldPlayer;

    public ObjectMp3PlayerAdapter(OldPlayer oldPlayer) {
        this.oldPlayer = oldPlayer;
    }

    @Override
    public void playVlc(String fileName) {
        System.out.println("对象适配器:播放 VLC 文件...");
        oldPlayer.playMp3(fileName);
    }

    @Override
    public void playMp4(String fileName) {
        System.out.println("对象适配器:播放 VLC 文件...");
        oldPlayer.playMp3(fileName);
    }
}

优点:

  • 遵循“合成/聚合复用原则”(Composite Reuse Principle),灵活性更高。
  • 不依赖继承,可适配任意具有特定方法的类。
  • 降低耦合度,易于维护和扩展。
  • 支持同时适配多个被适配者。

测试:

/**
 * 使用示例测试
 *
 * @author LS
 * @version 1.0
 * @createDate 2025/9/6 18:14
 **/
public class MusicPlayerApp {
    public static void main(String[] args) {
        ClassMp3PlayerAdapter classMp3PlayerAdapter=new ClassMp3PlayerAdapter();
        classMp3PlayerAdapter.playMp4("经典老歌.mp4");
        ObjectMp3PlayerAdapter objectMp3PlayerAdapter=new ObjectMp3PlayerAdapter(new OldPlayer());
        objectMp3PlayerAdapter.playVlc("经典老歌.vlc");
    }
}

测试结果:

2.3、类图

元素说明:

  • Target: 客户端所期待的接口。
  • Adaptee: 需要被适配的现有类。
  • Adapter: 适配器类,实现 Target 接口,并持有 Adaptee 的引用,负责将 Target 的请求转换为对 Adaptee 的调用。

三、总结

适配器模式是解决接口不兼容问题的经典设计模式。通过引入适配器作为中间层,实现接口的转换与适配,从而在不修改现有代码的前提下,实现新旧系统的集成。在 Java 开发中,推荐使用对象适配器模式,以获得更高的灵活性和可维护性。

掌握适配器模式,有助于构建更加灵活、可扩展和可维护的软件系统。

更多推荐