簡介
擴充卡模式(Adapter Pattern)是一種結構型設計模式,為兩個不相容的接口之間架設橋梁,使不相容的對象能夠互相合作。
當你希望使用某個類,但是其接口與其他代碼不相容時,可以使用擴充卡類。當你需要複用類的共同方法,但是這些共同的方法不是所有子類的共性,你可以通過擴充卡模式來相容。
作用
- 将一個類的接口轉換成另外一個接口。
- 使得原本不相容的接口也能一同工作。
實作步驟
- 有一些可以重複使用的類,這些類不一定有一緻的接口。
- 建立接口轉換類,将不同的類插入到轉換類中。
- 通過轉換類來實作(繼承或依賴)不同接口的調用。
UML
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIlxmYpRXYw12bj9CXiFGZ2cTM3IGOxYjZ2QDOhBjNxQzY0ATYiRmMyUTZyEzXy8CX0NWZqJ2bvwVawF2Lc52YuMHc35yZh5iai1yYzt2Lc9CX6MHc0RHaiojIsJye.jpg)
代碼
基礎接口類
// 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