設計模式學習-使用go實現介面卡模式

Rick.lz發表於2021-11-14

介面卡模式

定義

介面卡模式的英文翻譯是Adapter Design Pattern。顧名思義,這個模式就是用來做適配的,它將不相容的介面轉換為可相容的介面,讓原本由於介面不相容而不能一起工作的類可以一起工作。

舉個例子:

現在比較新款的電腦都有USB-C介面,但是我們目前的滑鼠鍵盤的介面都是傳統的USB介面,所以是不能使用的,這時候我們會買個轉介面來進行介面的轉接,那麼這個轉介面在設計模式中就是介面卡。

程式碼實現

// 基礎的播放功能
type MediaPlayer interface {
	play(audioType string, fileName string)
}

// 不同的播放器平臺
type AdvancedMediaPlayer interface {
	playVlc(fileName string)
	playMp4(fileName string)
}

// VlcPlayers
type VlcPlayers struct {
}

func (v *VlcPlayers) playVlc(fileName string) {
	fmt.Println("正在播放" + fileName)
}

func (v *VlcPlayers) playMp4(fileName string) {
	fmt.Println("格式不支援")
}

// Mp4Player
type Mp4Player struct {
}

func (m *Mp4Player) playVlc(fileName string) {
	fmt.Println("格式不支援")
}

func (m *Mp4Player) playMp4(fileName string) {
	fmt.Println("正在播放" + fileName)
}

// 介面卡
type MediaAdapter struct {
	MusicPlayer AdvancedMediaPlayer
}

func NewMediaAdapter(audioType string) *MediaAdapter {
	var mediaAdapter MediaAdapter
	switch audioType {
	case "vlc":
		mediaAdapter.MusicPlayer = &VlcPlayers{}
	case "mp4":
		mediaAdapter.MusicPlayer = &Mp4Player{}
	default:
		panic("不支援的型別")
	}
	return &mediaAdapter
}
func (m *MediaAdapter) play(audioType string, fileName string) {
	switch audioType {
	case "vlc":
		m.MusicPlayer.playVlc(fileName)
	case "mp4":
		m.MusicPlayer.playMp4(fileName)

	}
}

// AudioPlayer 音訊播放器類
type AudioPlayer struct {
	mediaAdapter *MediaAdapter
}

// Play 播放音訊
func (auPlayer *AudioPlayer) Play(audioType, fileName string) {
	if audioType == "mp3" {
		fmt.Println("正在播放" + fileName)
		return
	}
	auPlayer.mediaAdapter = NewMediaAdapter(audioType)
	auPlayer.mediaAdapter.play(audioType, fileName)
}

測試檔案

func TestPlayer(t *testing.T) {
	ad := AudioPlayer{}
	ad.Play("mp4", "荷塘月色")
	ad.Play("vlc", "小蘋果")
	ad.Play("mp3", "天空之城")
}

這裡做個簡單的分析

1、我們有一個 AudioPlayer ,但是隻能播放 mp3;

2、我們希望 AudioPlayer 也可以播放 mp3 和 vlc;

3、引入了一個 MediaAdapter ,通過介面卡來處理不支援的功能,對於 AudioPlayer 來講,它只用需要呼叫 MediaAdapter 就能實現各種播放格式音訊的播放;

4、MediaAdapter 對各種格式進行了包裝,不同的格式音訊,可以有用相同的呼叫方法。

放一張結構圖

adapter

優點

1、可以讓任何兩個沒有關聯的類一起執行。

2、提高了類的複用。

3、增加了類的透明度。

4、靈活性好。

缺點

過多地使用介面卡,會讓系統非常零亂,不易整體進行把握

一般來說,介面卡模式可以看作一種“補償模式”,用來補救設計上的缺陷。應用這種模式算是“無奈之舉”,如果在設計初期,我們就能協調規避介面不相容的問題,那這種模式就沒有應用的機會了。

如果大量的使用這種模式,可能就是我們的前期的設計有很大的問題,就需要考慮重構了

適用範圍

1、封裝有缺陷的介面設計

2、統一多個類的介面設計

3、替換依賴的外部系統

4、相容老版本介面

5、適配不同格式的資料

代理、橋接、裝飾器、介面卡4種設計模式的區別

代理模式:代理模式在不改變原始類介面的條件下,為原始類定義一個代理類,主要目的是控制訪問,而非加強功能,這是它跟裝飾器模式最大的不同。

橋接模式:橋接模式的目的是將介面部分和實現部分分離,從而讓它們可以較為容易、也相對獨立地加以改變。

裝飾器模式:裝飾者模式在不改變原始類介面的情況下,對原始類功能進行增強,並且支援多個裝飾器的巢狀使用。

介面卡模式:介面卡模式是一種事後的補救策略。介面卡提供跟原始類不同的介面,而代理模式、裝飾器模式提供的都是跟原始類相同的介面。

參考

【文中程式碼】https://github.com/boilingfrog/design-pattern-learning/tree/master/介面卡模式
【大話設計模式】https://book.douban.com/subject/2334288/
【極客時間】https://time.geekbang.org/column/intro/100039001
【菜鳥教程】https://www.runoob.com/design-pattern/adapter-pattern.html
【詩介面卡模式】https://boilingfrog.github.io/2021/11/14/使用go實現介面卡模式/

相關文章