設計模式-適配器模式(Go語言描寫敘述)
在上一篇博客設計模式-策略模式(Go語言描寫敘述)中我們用最簡單的代碼用go語言描寫敘述了設計模式中的策略模式,用最簡單的實例來描寫敘述相信能夠讓剛開始學習的人能夠非常輕松的掌握各種設計模式。繼上篇博客,我們接著用相同簡單的代碼來了解一下適配器模式。
適配器模式介紹
說起適配器模式,相信非常多做android的同學第一印象就是AdapterView的Adapter,那它是幹嘛用的呢?為什麽要叫adapter呢?要了解這個問題。我們首先來看看適配器模式的定義:
將一個類的接口轉換成客戶希望的另外一個接口。適配器模式使得原本由於接口不兼容而不能一起工作的那些類能夠一起工作。——Gang of Four
恩,看起來好像有點迷糊,舉個樣例吧:
我電腦的電源是三個插頭(也就是有地線)的那種,不知道為啥學校的插座都是兩個插孔的,哎呀,這可咋辦啊!同學建議我們買個轉換器,這種轉換器有三個插孔,我的電源能夠插進去,同一時候它還有兩個插頭,能夠插進學校的插座裏,嘿嘿,同學真聰明,這麽easy的就攻克了我的問題。
在上面的樣例裏,那個轉換器也能夠叫做適配器,我們如今要說的適配器模式靈感就是來自上述所述的實際生活中遇到的問題。那在我們程序設計中會遇到什麽樣的問題呢? 再來看個樣例:
應老師的要求,我們如今須要做一個音樂播放器,如今我算是知道一點面向對象的原則了,所以我首先設計了一個接口。這個接口有一個playMusic的方法,接著我非常輕松的利用這個接口設計出了一個音樂播放器,音樂控制器通過調用playMusic能夠完美的播放不論什麽音樂。嘖嘖嘖,高興中…老師對我的音樂播放器也非常愜意。只是他又提出了新的需求,讓我的音樂播放器也能夠播放遊戲的聲音。並給了我一個播放遊戲聲音的類。這個類也非常easy。僅僅有一個playSound方法,盡管非常easy,可是如今我困惑了,由於我設計的音樂控制器僅僅認識playMusic而不認識playSound,難道我要又一次設計我的音樂控制器嗎?正當我苦惱的時候,同學出如今了我身後,輕聲的告訴我:“適配器模式能夠完美的解決你的問題,你僅僅須要寫一個Adapter實現你的音樂播放接口,在這個Adapter的playMusic中去調用遊戲聲音播放器的playSound方法就能夠了。
”聽了同學的話。我突然恍然大悟。原來這就是適配器模式!
好了。通過上面的三個小段子,相信大家對適配器模式應該了有了大概的認識,以下還是用一張結構圖來清晰的描寫敘述一下什麽是適配器模式吧。
通過上面的圖我們也能夠看出來,適配器要做的事情就是讓我們寫的野實現適配到系統須要的標準實現上。以下我們迅速進去代碼模式,讓代碼告訴我們適配器模式張啥樣!
代碼實現
代碼實現環節,我們還是用上面那個音樂播放器的樣例,首先設計一個音樂播放的接口:
package player
type Player interface {
PlayMusic()
}
這個接口僅僅有一個方法PlayMusic
PlayMusic
這種方法達到播放音樂的目的。在來看看我們播放音樂的實現。
package player
import "fmt"
type MusicPlayer struct {
Src string
}
func (p MusicPlayer) PlayMusic() {
fmt.Println("play music: " + p.Src)
}
MusicPlayer
有一個方法是PlayMusic()
,所以它實現了Player
接口。來讓我們的音樂播放器播放器來吧,
package main
import . "./player"
func main() {
var player Player = MusicPlayer {Src:"music.mp3"}
play(player)
}
func play(player Player) {
player.PlayMusic()
}
代碼也超級簡單,一個play
方法去調用了Player
的實現的PlayMusic
方法。
來看看結果,
如今我們的音樂播放器能夠播放歌曲了。僅僅須要給出一個歌曲的路徑就ok,只是如今我們還須要播放遊戲聲音。而且給了我們一個這種實現。
package player
import "fmt"
type GameSoundPlayer struct {
Src string
}
func (p GameSoundPlayer) PlaySound() {
fmt.Println("play sound: " + p.Src)
}
GameSoundPlayer
也是有一個Src
屬性,也有一個方法,只是這種方法叫PlaySound
。並非我們須要的PlayMusic
,那可咋辦呢?別忘了咱們的play
方法
須要的是一個Player
的實現,並自己主動調用了PlayMusic
方法,以下本節的主角-GameSoundAdapter
出場。
package player
type GameSoundAdapter struct {
SoundPlayer GameSoundPlayer
}
func (p GameSoundAdapter) PlayMusic() {
p.SoundPlayer.PlaySound()
}
GameSoundAdapter
有一個GameSoundPlayer
類型的屬性。它就是我們上面的那個遊戲聲音播放器。GameSoundPlayer
另一個方法名字叫PlayMusic
。所以GameSoundPlayer
實現了Player
接口,我們能夠把它用於player
方法中,在PlayMusic
中我們是調用的GameSoundPlayer
的PlaySound
來播放聲音的。
來看看我們這個適配器適配的咋樣,
package main
import . "./player"
func main() {
gameSound := GameSoundPlayer {Src:"game.mid"}
gameAdapter := GameSoundAdapter {SoundPlayer:gameSound}
play(gameAdapter)
}
func play(player Player) {
player.PlayMusic()
}
看main函數中,首先我們還是有一個GameSoundPlayer
類型的變量,然後將它賦值給了GameSoundAdapter
的SoundPlayer
屬性。以下調用GameSoundAdapter
的PlayMusic
方法,就能夠間接的調用GameSoundPlayer
的PlaySound
方法了,這樣我們就輕松的將GameSoundPlayer
適配到了Player
。
來看看結果:
總體來看我們的代碼還是非常easy,只是簡單的代碼已經將適配器模式解說的非常清晰了,那最後我們來思考一個問題,適配器模式體現了哪些面向對象的設計原則呢?針對接口編程有木有? 開閉原則有木有?
好了。適配器模式我們就講到這裏,最後是文章的實例代碼下載:http://download.csdn.net/detail/qibin0506/9420484
設計模式-適配器模式(Go語言描寫敘述)