适配器模式(Adapter Pattern)

概念

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。

适配器模式的主要作用是把原本不兼容的接口通过适配修改做到统一,方便调用方使用.

简介

作用及优势

    - 将原本老接口适配成新需求的新接口

    - 将原本不兼容的类,兼容到一起工作

    - 提高接口的复用率

    - 接口灵活性较好

    - 代码侵入性较低

不足之处

    - 真假不分,适配之后的功能和之前的功能混淆

    - 适配器过多,导致系统结构很乱

场景

    - jvm的跨平台

    - jdbc的多数据类型链接

    - 各个操作系统上的App

    

适配器一般都是在系统开发到中期,或者后期迭代中才会增加;项目之处最好考虑兼容性问题,全局观做好,后期的话适配就会大量减少;

代码

案例描述

有一个远古的MP3播放器,正在努力的播放MP3文件,突然新生想法,我要播放MP4文件,甚至avi文件;然后开始动手做了个适配器(MediaAdapter),然后给他赋予了播放前面两种文件的能力,然后在把适配器插入到之前老的MP3播放器中,然后就可以美滋滋的看着avi文件的电影了;

美滋滋.gif

工程目录

适配器模式.jpg

项目类图

适配器.jpg

具体实现

媒体抽象类(MediaPlayer) :这里就是有个播放的功能;

/**
 * 功能描述: 媒体播放器
 *
 * @author: WuChengXing
 * @create: 2021-06-20 12:52
 **/
public interface MediaPlayer {
    /**
     * 播放功能
     *
     * @param audioType
     * @param fileName
     */
    void play(String audioType, String fileName);
}

高级的播放器(AdvancedMediaPlayer) :具有播放多种文件格式的播放功能;


/**
 * 功能描述: 多功能播放器
 *
 * @author: WuChengXing
 * @create: 2021-06-20 12:54
 **/
public interface AdvancedMediaPlayer {
    void playAvi(String fileName);

    void playMp4(String fileName);
}

两个实现类(Mp4Player、AviPlayer):MP4播放器和avi文件播放器;

/**
 * @author: WuChengXing
 * @create: 2021-06-20 12:56
 **/
public class Mp4Player implements AdvancedMediaPlayer {
    @Override
    public void playAvi(String fileName) {

    }

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

---------------------------------- 

/**
 * @author: WuChengXing
 * @create: 2021-06-20 12:55
 **/
public class AviPlayer implements AdvancedMediaPlayer {
    @Override
    public void playAvi(String fileName) {
        System.out.println("Playing avi file. Name: "+ fileName);
    }

    @Override
    public void playMp4(String fileName) {

    }
} 

适配器(MediaAdapter)

/**
 * 功能描述: 多功能媒体适配器,相当于将高级媒体播放器的功能放到适配器中,
 * 当之前老的播放器想要播放其他媒体文件时,插上适配器就行了
 *
 * @author: WuChengXing
 * @create: 2021-06-20 12:57
 **/
public class MediaAdapter implements MediaPlayer {
    /**
     * 高级媒体播放器,啥玩意都能播放
     */
    AdvancedMediaPlayer advancedMediaPlayer;

    public MediaAdapter(String audioType) {
        if (audioType.equalsIgnoreCase("avi")) {
            advancedMediaPlayer = new AviPlayer();
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMediaPlayer = new Mp4Player();
        }
    }

    /**
     * 通过适配器来播放不同文件的音频或视屏
     * @param audioType
     * @param fileName
     */
    @Override
    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("avi")) {
            advancedMediaPlayer.playAvi(fileName);
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMediaPlayer.playMp4(fileName);
        }
    }
}

这里相当于将高级媒体播放器 的功能赋予给适配器

MP3播放器(Mp3AudioPlayer) :这个就是之前老的接口(功能);

/**
 * 功能描述: 真正的视频播放器
 *
 * @author: WuChengXing
 * @create: 2021-06-20 13:00
 **/
public class Mp3AudioPlayer implements MediaPlayer {

    private MediaAdapter mediaAdapter;

    @Override
    public void play(String audioType, String fileName) {
        //播放 mp3 音乐文件的内置支持
        if(audioType.equalsIgnoreCase("mp3")){
            System.out.println("Playing mp3 file. Name: "+ fileName);
        }
        //mediaAdapter 提供了播放其他文件格式的支持
        else if(audioType.equalsIgnoreCase("avi")
                || audioType.equalsIgnoreCase("mp4")){
            mediaAdapter = new MediaAdapter(audioType);
            mediaAdapter.play(audioType, fileName);
        }
        else{
            System.out.println("Invalid media. "+
                    audioType + " format not supported");
        }
    }
}

可以理解为这里插上了适配器,使得之前老的MP3都能播放MP4和avi了;

测试


/**
 * 功能描述: 适配器测试
 *
 * @author: WuChengXing
 * @create: 2021-06-19 14:15
 **/
public class AdapterTest {
    public static void main(String[] args) {
        Mp3AudioPlayer mp3AudioPlayer = new Mp3AudioPlayer();
        mp3AudioPlayer.play("mp3", "test.mp3");
        mp3AudioPlayer.play("mp4", "test.mp4");
        mp3AudioPlayer.play("avi", "test.avi");
    }
}

结果:

Playing mp3 file. Name: test.mp3
Playing mp4 file. Name: test.mp4
Playing avi file. Name: test.avi