天天看點

不同語言實作擴充卡模式(Adapter Pattern)詳解簡介作用實作步驟UML代碼

簡介

擴充卡模式(Adapter Pattern)是一種結構型設計模式,為兩個不相容的接口之間架設橋梁,使不相容的對象能夠互相合作。

當你希望使用某個類,但是其接口與其他代碼不相容時,可以使用擴充卡類。當你需要複用類的共同方法,但是這些共同的方法不是所有子類的共性,你可以通過擴充卡模式來相容。

作用

  1. 将一個類的接口轉換成另外一個接口。
  1. 使得原本不相容的接口也能一同工作。

實作步驟

  1. 有一些可以重複使用的類,這些類不一定有一緻的接口。
  1. 建立接口轉換類,将不同的類插入到轉換類中。
  1. 通過轉換類來實作(繼承或依賴)不同接口的調用。

UML

不同語言實作擴充卡模式(Adapter Pattern)詳解簡介作用實作步驟UML代碼

代碼

基礎接口類

// MediaPlayer.java 定義視訊/音頻的格式播放接口
public interface MediaPlayer {
  public void play();
  public void setFileType(String fileType);
  public void setFilePath(String filePath);
}
           

具體播放器實作類,可以多個

// AudioPlayer.java 支援多種音頻格式播放,相對簡單,不區分格式
public class AudioPlayer implements MediaPlayer {
  private String fileType;
  private String filePath;

  public AudioPlayer(String fileType, String filePath) {
    this.fileType = fileType;
    this.filePath = filePath;
  }

  public void play() {
    System.out.println("AudioPlayer fileType:" + fileType + " | filePath:" + filePath);
    if (fileType.equals("mp3")) {
      System.out.println("AudioPlayer::play() mp3");
    } else if (fileType.equals("mp4")) {
      System.out.println("AudioPlayer::play() mp4");
    }
  }
}
           
// HlsPlayer.java 播放器實作了視訊接口
public class HlsPlayer implements MediaPlayer {
  private String fileType;
  private String filePath;

  public HlsPlayer(String fileType, String filePath) {
    this.fileType = fileType;
    this.filePath = filePath;
  }

  public void play() {
    System.out.println("HlsPlayer fileType:" + fileType + " | filePath:" + filePath);
    System.out.println("HlsPlayer::play()");
  }
}
           
// Mp4Player.java 播放器實作了視訊接口
public class Mp4Player implements MediaPlayer {
  private String fileType;
  private String filePath;

  public Mp4Player(String fileType, String filePath) {
    this.fileType = fileType;
    this.filePath = filePath;
  }

  public void play() {
    System.out.println("Mp4Player fileType:" + fileType + " | filePath:" + filePath);
    System.out.println("Mp4Player::play()");
  }
}
           

擴充卡類

// PlayerAdapter.java 擴充卡類,可以播放各種音頻和視訊,外部調用方式一樣。擴充卡也可以實作基礎播放接口
public class PlayerAdapter implements MediaPlayer {

  private String mediaType;
  private String fileType;
  private String filePath;
  private MediaPlayer mp4Player;
  private MediaPlayer hlsPlayer;
  private MediaPlayer audioPlayer;

  public PlayerAdapter(String mediaType, String fileType, String filePath) {
    this.mediaType = mediaType;
    this.fileType = fileType;
    if (mediaType.equals("video")) {
      if (fileType.equals("mp4")) {
        setMp4Player(fileType, filePath);
      } else if (fileType.equals("hls")) {
        setHlsPlayer(fileType, filePath);
      }
    } else if (mediaType.equals("audio")) {
      setAudioPlayer(fileType, filePath);
    }
  }

  public void setMp4Player(String fileType, String filePath) {
    if (mp4Player == null) {
      mp4Player = new Mp4Player(fileType, filePath);
    } else {
      mp4Player.setFileType(fileType);
      mp4Player.setFilePath(filePath);
    }
  }

  public void setHlsPlayer(String fileType, String filePath) {
    if (hlsPlayer == null) {
      hlsPlayer = new HlsPlayer(fileType, filePath);
    } else {
      hlsPlayer.setFileType(fileType);
      hlsPlayer.setFilePath(filePath);
    }
  }

  public void setAudioPlayer(String fileType, String filePath) {
    if (audioPlayer == null) {
      audioPlayer = new AudioPlayer(fileType, filePath);
    } else {
      audioPlayer.setFileType(fileType);
      audioPlayer.setFilePath(filePath);
    }
  }

  // 通用的适配接口
  public void play() {
    if (this.mediaType.equals("audio")) {
      audioPlayer.play();
    } else if (this.mediaType.equals("video")) {
      if (this.fileType.equals("mp4")) {
        mp4Player.play();
      } else if (this.fileType.equals("hls")) {
        hlsPlayer.play();
      }
    }
  }

  public void setFileType(String fileType) {
    this.fileType = fileType;
  }

  public String getFileType() {
    return fileType;
  }

  public void setFilePath(String filePath) {
    this.filePath = filePath;
  }

  public String getFilePath() {
    return filePath;
  }
}
           

測試調用

/**
     * 擴充卡模式是當調用方需需調用不同功能,但接口并不相容時,
     * 這時候可通過一個擴充卡類來做适配,讓調用方通過适配類再去調用各個對象的功能。
     * 調用方隻知道擴充卡,而不知道後面的其他對象。
     */

    // mp4播放
    PlayerAdapter playerAdapter1 = new PlayerAdapter("video", "mp4", "d:/video.mp4");
    playerAdapter1.play();
    // 複用執行個體播音頻
    playerAdapter1.play("audio", "mp4", "d:/audio.mp4");

    // hls播放
    PlayerAdapter playerAdapter2 = new PlayerAdapter("video", "hls", "http://video.m3u8");
    playerAdapter2.play();

    // mp3播放
    PlayerAdapter playerAdapter3 = new PlayerAdapter("audio", "mp3", "d:/audio.mp3");
    playerAdapter3.play();

    // mp4音頻播放
    PlayerAdapter playerAdapter4 = new PlayerAdapter("audio", "mp4", "d:/audio.mp4");
    playerAdapter4.play();
    // 複用執行個體播視訊
    playerAdapter4.play("video", "hls", "d:/video.m3u8");
           

更多語言版本

不同語言實作設計模式:https://github.com/microwind/design-pattern

不同語言實作擴充卡模式(Adapter Pattern)詳解簡介作用實作步驟UML代碼