设计模式笔记_结构型_适配器模式

1.适配器模式介绍

适配器模式是一种结构型设计模式,它允许不兼容的接口协同工作。适配器模式的核心思想是将一个类的接口转换成客户期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。

你可以将其想象成一个"转换插头"------假设你有一个中国的电器插头,但你在欧洲旅行,需要将它插入欧洲的插座。适配器就是那个可以让中国插头插入欧洲插座的转换器。

在软件开发中,适配器模式通常用于整合一些旧的代码或第三方库,使它们能够与新的系统一起工作,而不需要修改它们的内部实现。适配器模式通过创建一个"适配器类",这个类在内部转换接口,使得不兼容的接口可以顺利地互操作。

适配器模式通常包含以下几个角色:

  1. 目标接口(Target):这是客户期望的接口,目标可以是具体的或抽象的类。
  2. 适配者(Adaptee):这是需要适配的类,拥有客户希望使用的功能,但接口不兼容。
  3. 适配器(Adapter):通过在内部包装一个适配者对象,把适配者的接口转换为目标接口。

2. 代码演示

场景说明:我们创建一个媒体播放器MediaPlayer作为目标接口,一个老的媒体播放器OldMediaPlayer(接口及其实现)作为适配者,并且通过MediaAdapter 类实现了适配器,最终实现复用老媒体播放器功能。

目标接口:

java 复制代码
public interface MediaPlayer {
    void play(String audioType, String fileName);
}

**适配者:**OldMediaPlayer及其实现类

java 复制代码
//老媒体播放器,里面有希望使用的功能
public interface OldMediaPlayer {
    void playVlc(String fileName);
    void playMp4(String fileName);
}

//map4播放器
public class Mp4Player implements OldMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        // Do nothing
    }

    @Override
    public void playMp4(String fileName) {
        System.out.println("Playing mp4 file. Name: " + fileName);
    }
}

//vlc播放器
public class VlcPlayer implements OldMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        System.out.println("Playing vlc file. Name: " + fileName);
    }

    @Override
    public void playMp4(String fileName) {
        // Do nothing
    }
}

适配器:

java 复制代码
//适配器:通过在内部包装一个适配者对象,把适配者的接口转换为目标接口
public class MediaAdapter implements MediaPlayer {
    
    //实现了 MediaPlayer 接口并使用 OldMediaPlayer 的实例
    OldMediaPlayer oldMediaPlayer;

    public MediaAdapter(String audioType){
        if(audioType.equalsIgnoreCase("vlc") ){
            oldMediaPlayer = new VlcPlayer();
        } else if (audioType.equalsIgnoreCase("mp4")){
            oldMediaPlayer = new Mp4Player();
        }
    }

    @Override
    public void play(String audioType, String fileName) {
        if(audioType.equalsIgnoreCase("vlc")){
            oldMediaPlayer.playVlc(fileName);
        }else if(audioType.equalsIgnoreCase("mp4")){
            oldMediaPlayer.playMp4(fileName);
        }
    }
}

使用适配器

java 复制代码
//使用适配器来播放不同格式的音频文件
public class AudioPlayer implements MediaPlayer {
    MediaAdapter mediaAdapter;

    @Override
    public void play(String audioType, String fileName) {
        // Inbuilt support for mp3 music files
        if(audioType.equalsIgnoreCase("mp3")){
            System.out.println("Playing mp3 file. Name: "+ fileName);
        }
        // MediaAdapter is providing support to play other file formats
        else if(audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")){
            mediaAdapter = new MediaAdapter(audioType);
            mediaAdapter.play(audioType, fileName);
        }
        else{
            System.out.println("Invalid media. " + audioType + " format not supported");
        }
    }
}
java 复制代码
public class Demo {
    public static void main(String[] args) {
        AudioPlayer audioPlayer = new AudioPlayer();

        audioPlayer.play("mp3", "beyond the horizon.mp3");
        audioPlayer.play("mp4", "alone.mp4");
        audioPlayer.play("vlc", "far far away.vlc");
        audioPlayer.play("avi", "mind me.avi");
    }
}

上述例子中,MediaAdapter类充当了适配器的角色,通过实现 MediaPlayer 接口,并在内部调用 OldMediaPlayerplayXXX() 方法,实现了接口的兼容。这样,新的音频系统就可以使用旧的播放器来播放音乐,而不需要对旧的播放器进行任何修改。