设计模式——适配器模式

421 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。 最常用来描述适配器模式的就是“读卡器”

概述

读卡器可以将“电脑”和“SD卡”本来无法一起工作的东西结合起来

所以适配者模式就是使由于接口不兼容而不能一起工作的那些类一起工作起来

适用环境

  1. 目前一些老系统的接口,新系统不适配
  2. 一些接口开发出来供通用逻辑,但是具体的逻辑又需要一些特殊的处理

一般适配器模式,不是在软件开发初期进行的,一般都是在后期进行补丁修改时使用

逻辑实现

继承或依赖

  1. 有原始的两个播放器,一个播放mp4,一个播放vlc
  2. 新款播放器即可以播放mp4,又可以播放vlc(其本质是判断预要播放的音频格式来匹配内部的播放接口)
  3. 这个匹配两个播放器的逻辑就是一个适配器的逻辑

源角色通过适配器角色去调用目标角色

  • 目标角色(target)
  • 源角色(adaptee)
  • 适配器角色(adapter)

菜鸟教程——适配器模式UML图

我们想要让 AudioPlayer 播放其他格式的音频文件。为了实现这个功能,我们需要创建一个实现了 MediaPlayer 接口的适配器类 MediaAdapter,并使用 AdvancedMediaPlayer 对象来播放所需的格式。

代码实现

  1. 创建原始播放器的接口和支持vlc和mp4的接口
/**
 * @ClassName MediaPlayer
 * @Desc 原始播放器处理器
 * @Author ymy
 * @Date 2021/10/25 2:23 下午
 * @Version 1.0
 **/
public interface MediaPlayer {
    public void play(String audioType, String fileName);
}

/**
 * @ClassName AdvancedMediaPlayer
 * @Desc 升级播放器处理器
 * @Author ymy
 * @Date 2021/10/25 2:23 下午
 * @Version 1.0
 **/
public interface AdvancedMediaPlayer {
    public void playVlc(String fileName);
    public void playMp4(String fileName);
}
  1. 创建最新的媒体播放器的实现
/**
 * @ClassName VlcPlayer
 * @Desc vlc格式播放器
 * @Author ymy
 * @Date 2021/10/25 2:24 下午
 * @Version 1.0
 **/
public class VlcPlayer implements AdvancedMediaPlayer{
    @Override
    public void playVlc(String fileName) {
        System.out.println("Playing vlc file. Name: "+ fileName);
    }

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

/**
 * @ClassName Mp4Player
 * @Desc mp4格式播放器
 * @Author ymy
 * @Date 2021/10/25 2:25 下午
 * @Version 1.0
 **/
public class Mp4Player implements AdvancedMediaPlayer{
    @Override
    public void playVlc(String fileName) {
        //do nothing
    }

    @Override
    public void playMp4(String fileName) {
        System.out.println("Playing mp4 file. Name: "+ fileName);
    }
}
  1. 将原始播放器处理器适配到最新的播放器处理器上
/**
 * @ClassName MediaAdapter
 * @Desc 将原始播放器处理器适配到最新的播放器处理器上
 * @Author ymy
 * @Date 2021/10/25 2:26 下午
 * @Version 1.0
 **/
public class MediaAdapter implements MediaPlayer{

    AdvancedMediaPlayer advancedMusicPlayer;


    @Override
    public void play(String audioType, String fileName) {
        if(audioType.equalsIgnoreCase("vlc")){
            advancedMusicPlayer = new VlcPlayer();
            advancedMusicPlayer.playVlc(fileName);
        }else if(audioType.equalsIgnoreCase("mp4")){
            advancedMusicPlayer = new Mp4Player();
            advancedMusicPlayer.playMp4(fileName);
        }
    }
}
  1. 创建原始播放器的实现类
/**
 * @ClassName AudioPlayer
 * @Desc 媒体播放器,继承MediaPlayer接口原本只支持mp3格式的播放,现在需要支持mp4或者vlc格式(但是mp4格式和vlc格式的播放器接口不支持)使用适配器接口中间调用
 * @Author ymy
 * @Date 2021/10/25 2:28 下午
 * @Version 1.0
 **/
public class AudioPlayer implements MediaPlayer {
    MediaAdapter mediaAdapter;

    /**
     * 我们想要让 AudioPlayer 播放其他格式的音频文件。
     * 为了实现这个功能,
     * 我们需要创建一个实现了 MediaPlayer 接口的适配器类 MediaAdapter,
     * 并使用 AdvancedMediaPlayer 对象来播放所需的格式。
     *
     * @param audioType
     * @param fileName
     */

    @Override
    public void play(String audioType, String fileName) {

        if (audioType.equalsIgnoreCase("mp3")) {
            //播放 mp3 音乐文件的内置支持
            System.out.println("Playing mp3 file. Name: " + fileName);
        } else if (audioType.equalsIgnoreCase("vlc")
                || audioType.equalsIgnoreCase("mp4")) {
            //mediaAdapter 提供了播放其他文件格式的支持
            //使用type创建对应的接口实现类,再调用具体方法来实现功能
            mediaAdapter.play(audioType, fileName);
        } else {
            System.out.println("Invalid media. " +
                    audioType + " format not supported");
        }
    }
}
  1. 调用实现
public class AdapterPatternDemo {
   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");
   }
}

功能目的,将原本只支持mp3格式播放的AudioPlayer播放器,使其支持mp4和vlc格式,而且因为接口参数不同,所以中间使用adapter来进行适配