适配器模式

简介

定义: 将一个类的接口转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以相互合作。适配器的功能就是把一个接口转成另一个接口。

使用场景:

  • 接口不兼容的类之间的适配

  • 第三方库的接口适配

  • 旧系统接口适配

实现方式:

  • 类适配器(继承)

  • 对象适配器(组合)★推荐

  • 接口适配器

UML

代码示例

  1. 现有播放器接口

public interface AdvancedMediaPlayer {
    
    /**
     * 播放VLC格式文件
     */
    void playVlc(String fileName);
    
    /**
     * 播放MP4格式文件
     */
    void playMp4(String fileName);
    
    /**
     * 停止播放
     */
    void stop();
}
  1. 现有播放器实现

public class Mp3Player {

    /**
     * 播放MP3文件
     */
    public void playMp3(String fileName) {
        System.out.println("🎵 MP3播放器正在播放: " + fileName);
        System.out.println("   - 支持MP3音频解码");
        System.out.println("   - 支持ID3标签显示");
        System.out.println("   - 支持播放列表");
    }

    /**
     * 停止播放
     */
    public void stop() {
        System.out.println("⏹️ MP3播放器停止播放");
    }

    /**
     * 暂停播放
     */
    public void pause() {
        System.out.println("⏸️ MP3播放器暂停播放");
    }
}
public class Mp4Player implements AdvancedMediaPlayer {

    @Override
    public void playVlc(String fileName) {
        System.out.println("❌ MP4播放器不支持VLC格式: " + fileName);
    }

    @Override
    public void playMp4(String fileName) {
        System.out.println("🎬 MP4播放器正在播放: " + fileName);
        System.out.println("   - 支持H.264视频编码");
        System.out.println("   - 支持AAC音频编码");
        System.out.println("   - 支持高清播放");
    }

    @Override
    public void stop() {
        System.out.println("⏹️ MP4播放器停止播放");
    }
}
public class VlcPlayer implements AdvancedMediaPlayer {

    @Override
    public void playVlc(String fileName) {
        System.out.println("🎬 VLC播放器正在播放: " + fileName);
        System.out.println("   - 支持高级视频解码");
        System.out.println("   - 支持字幕显示");
        System.out.println("   - 支持多种音频格式");
    }

    @Override
    public void playMp4(String fileName) {
        System.out.println("❌ VLC播放器不支持MP4格式: " + fileName);
    }

    @Override
    public void stop() {
        System.out.println("⏹️ VLC播放器停止播放");
    }
}
  1. 现有播放器进行适配接口,适配后对外统一提供

public interface MediaPlayer {
    
    /**
     * 播放音频文件
     * @param audioType 音频类型
     * @param fileName 文件名
     */
    void play(String audioType, String fileName);
    
    /**
     * 停止播放
     */
    void stop();
    
    /**
     * 暂停播放
     */
    void pause();
}
  1. 现有播放器进行适配实现

public class AudioPlayer implements MediaPlayer {
    
    private MediaAdapter mediaAdapter;
    private Mp3Player mp3Player;
    
    @Override
    public void play(String audioType, String fileName) {
        // 内置支持MP3格式
        if ("mp3".equalsIgnoreCase(audioType)) {
            if (mp3Player == null) {
                mp3Player = new Mp3Player();
            }
            mp3Player.playMp3(fileName);
        }
        // 对于其他格式,使用适配器
        else if ("vlc".equalsIgnoreCase(audioType) || 
                 "mp4".equalsIgnoreCase(audioType)) {
            mediaAdapter = new MediaAdapter(audioType);
            mediaAdapter.play(audioType, fileName);
        }
        else {
            System.out.println("❌ 不支持的音频格式: " + audioType);
        }
    }
    
    @Override
    public void stop() {
        System.out.println("⏹️ 音频播放器停止播放");
        if (mediaAdapter != null) {
            mediaAdapter.stop();
        }
        if (mp3Player != null) {
            mp3Player.stop();
        }
    }
    
    @Override
    public void pause() {
        System.out.println("⏸️ 音频播放器暂停播放");
        if (mediaAdapter != null) {
            mediaAdapter.pause();
        }
        if (mp3Player != null) {
            mp3Player.pause();
        }
    }
}
public class MediaAdapter implements MediaPlayer {
    
    private AdvancedMediaPlayer advancedMediaPlayer;
    
    /**
     * 构造函数 - 创建高级媒体播放器
     */
    public MediaAdapter(String audioType) {
        if ("vlc".equalsIgnoreCase(audioType)) {
            advancedMediaPlayer = new VlcPlayer();
        } else if ("mp4".equalsIgnoreCase(audioType)) {
            advancedMediaPlayer = new Mp4Player();
        } else {
            throw new IllegalArgumentException("不支持的音频格式: " + audioType);
        }
    }
    
    @Override
    public void play(String audioType, String fileName) {
        if ("vlc".equalsIgnoreCase(audioType)) {
            advancedMediaPlayer.playVlc(fileName);
        } else if ("mp4".equalsIgnoreCase(audioType)) {
            advancedMediaPlayer.playMp4(fileName);
        } else {
            System.out.println("❌ 适配器不支持该格式: " + audioType);
        }
    }
    
    @Override
    public void stop() {
        if (advancedMediaPlayer != null) {
            advancedMediaPlayer.stop();
        }
    }
    
    @Override
    public void pause() {
        if (advancedMediaPlayer != null) {
            System.out.println("⏸️ 高级播放器暂停播放");
        }
    }
}
  1. 使用方式

public class Test {

    public static void main(String[] args) {
        System.out.println("=== 适配器模式 - 媒体播放器示例 ===\n");

        // 创建音频播放器
        AudioPlayer audioPlayer = new AudioPlayer();

        System.out.println("--- 测试内置支持的格式 ---");
        // 测试内置支持的MP3格式
        audioPlayer.play("mp3", "song.mp3");
        audioPlayer.pause();
        audioPlayer.stop();
        
        System.out.println("\n--- 测试需要适配的格式 ---");
        
        // 测试VLC格式(通过适配器)
        audioPlayer.play("vlc", "movie.vlc");
        audioPlayer.pause();
        audioPlayer.stop();
        
        System.out.println();
        
        // 测试MP4格式(通过适配器)
        audioPlayer.play("mp4", "video.mp4");
        audioPlayer.pause();
        audioPlayer.stop();
        
        System.out.println("\n--- 测试不支持的格式 ---");
        // 测试不支持的格式
        audioPlayer.play("avi", "movie.avi");
        
        System.out.println("\n=== 适配器模式演示完成 ===");
        
        System.out.println("\n=== 适配器模式说明 ===");
        System.out.println("1. 目标接口: MediaPlayer - 定义客户端期望的接口");
        System.out.println("2. 被适配者: AdvancedMediaPlayer - 需要适配的现有接口");
        System.out.println("3. 适配器: MediaAdapter - 将现有接口转换为目标接口");
        System.out.println("4. 客户端: AudioPlayer - 使用目标接口的类");
        
        System.out.println("\n=== 适配器模式优势 ===");
        System.out.println("✅ 接口转换: 让不兼容的接口能够协同工作");
        System.out.println("✅ 代码复用: 可以复用现有的类而不需要修改");
        System.out.println("✅ 解耦合: 客户端不需要了解具体的实现细节");
        System.out.println("✅ 扩展性: 易于添加新的适配器支持更多格式");
        
        System.out.println("\n=== 适配器模式类型 ===");
        System.out.println("📌 类适配器: 通过继承实现适配(本例未使用)");
        System.out.println("📌 对象适配器: 通过组合实现适配(本例使用)");
        System.out.println("📌 接口适配器: 通过抽象类实现适配(本例未使用)");
    }
}

Last updated

Was this helpful?