Go設(shè)計模式之享元模式講解和代碼示例
Go 享元模式講解和代碼示例
概念示例
在游戲 《反恐精英》 中, 恐怖分子和反恐精英身著不同類型的衣物。 為了簡便起見, 我們就假設(shè)雙方都各有一種服裝類型。 服裝對象嵌入在玩家對象之中, 如下所示。
下面是玩家的結(jié)構(gòu)體。 我們可以看到, 服裝對象是嵌入在玩家結(jié)構(gòu)體之中的:
type player struct { dress dress playerType string // 可為 T 或 CT lat int long int }
假設(shè)目前有 5 名恐怖分子和 5 名反恐精英, 一共是 10 名玩家。 那么關(guān)于服裝, 我們就有兩個選項了。
- 10 個玩家對象各自創(chuàng)建不同的服裝對象, 并將其嵌入。 總共會創(chuàng)建 10 個服裝對象。
- 我們創(chuàng)建兩個服裝對象:
- 單一恐怖分子服裝對象: 其將在 5 名恐怖分子之間共享。
- 單一反恐精英服裝對象: 其將在 5 名反恐精英之間共享。
你可以看到, 方法 1 中我們總共創(chuàng)建了 10 個服裝對象; 方法 2 中則只有 2 個服裝對象。 第二種方法, 就是我們所遵循的享元設(shè)計模式。 我們所創(chuàng)建的 2 個服裝對象被稱為是享元對象。
享元模式會從對象中提取出公共部分并創(chuàng)建享元對象。 這些享元對象 (服裝) 隨后可在多個對象 (玩家) 中分享。 這極大地減少了服裝對象的數(shù)量, 更棒的是即便你創(chuàng)建了更多玩家, 也只需這么兩個服裝對象就足夠了。
在享元模式中, 我們會將享元對象存儲在 map 容器中。 每當(dāng)創(chuàng)建共享享元對象的其他對象時, 都會從 map 容器中獲取享元對象。
下面讓我們來看看此類安排的內(nèi)部狀態(tài)和外部狀態(tài):
- 內(nèi)部狀態(tài): 內(nèi)部狀態(tài)的服裝可在多個恐怖分子和反恐精英對象間共享。
- 外部狀態(tài): 玩家位置和玩家所使用的武器就是外部狀態(tài), 因為其在每個對象中都是不同的。
dressFactory.go: 享元工廠
package main import "fmt" const ( //TerroristDressType terrorist dress type TerroristDressType = "tDress" //CounterTerrroristDressType terrorist dress type CounterTerrroristDressType = "ctDress" ) var ( dressFactorySingleInstance = &DressFactory{ dressMap: make(map[string]Dress), } ) type DressFactory struct { dressMap map[string]Dress } func (d *DressFactory) getDressFactoryByType(dressType string) (Dress, error) { if d.dressMap[dressType] != nil { return d.dressMap[dressType], nil } if dressType == TerroristDressType { d.dressMap[dressType] = newTerrorisDress() return d.dressMap[dressType], nil } if dressType == CounterTerrroristDressType { d.dressMap[dressType] = newCounterTerrroristDress() return d.dressMap[dressType], nil } return nil, fmt.Errorf("Wrong dress type passed") } func getDressFactorySingleInstance() *DressFactory { return dressFactorySingleInstance }
dress.go: 享元接口
package main // 享元接口 type Dress interface { getColor() string }
terroristDress.go: 具體享元對象
package main type TerroristDress struct { color string } func (t *TerroristDress) getColor() string { return t.color } func newTerrorisDress() *TerroristDress { return &TerroristDress{color: "red"} }
counterTerroristDress.go: 具體享元對象
package main // 享元接口 type CounterTerrroristDress struct { color string } func (c *CounterTerrroristDress) getColor() string { return c.color } func newCounterTerrroristDress() *CounterTerrroristDress { return &CounterTerrroristDress{color: "green"} }
player.go: 背景
package main type Player struct { dress Dress playerType string lat int long int } func newPlayer(playerType, dressType string) *Player { dress, _ := getDressFactorySingleInstance().getDressFactoryByType(dressType) return &Player{ dress: dress, playerType: playerType, } } func (p *Player) newLocation(lat, long int) { p.lat = lat p.long = long }
game.go: 客戶端代碼
package main type game struct { terrorists []*Player counterTerrorists []*Player } func newGame() *game { return &game{ terrorists: make([]*Player, 1), counterTerrorists: make([]*Player, 01), } } func (c *game) addTerrorist(dressType string) { player := newPlayer("T", dressType) c.terrorists = append(c.terrorists, player) return } func (c *game) addCounterTerrorist(dressType string) { player := newPlayer("CT", dressType) c.counterTerrorists = append(c.counterTerrorists, player) return }
main.go: 客戶端代碼
package main import "fmt" func main() { game := newGame() //Add Terrorist game.addTerrorist(TerroristDressType) game.addTerrorist(TerroristDressType) game.addTerrorist(TerroristDressType) game.addTerrorist(TerroristDressType) //Add CounterTerrorist game.addCounterTerrorist(CounterTerrroristDressType) game.addCounterTerrorist(CounterTerrroristDressType) game.addCounterTerrorist(CounterTerrroristDressType) dressFactoryInstance := getDressFactorySingleInstance() for dressType, dress := range dressFactoryInstance.dressMap { fmt.Printf("DressColorType: %s\nDressColor: %s\n", dressType, dress.getColor()) } }
output.txt: 執(zhí)行結(jié)果
DressColorType: tDress
DressColor: red
DressColorType: ctDress
DressColor: green
到此這篇關(guān)于Go設(shè)計模式之享元模式講解和代碼示例的文章就介紹到這了,更多相關(guān)Go 享元模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Go如何基于現(xiàn)有的context創(chuàng)建新的context
在?Golang?中,context?包提供了創(chuàng)建和管理上下文的功能,那么在GO語言中如何基于現(xiàn)有的context創(chuàng)建新的context,下面小編就來和大家詳細(xì)聊聊2024-01-01Go1.20最新資訊go?arena手動管理內(nèi)存鴿了
由于過于繁雜,Go?核心團隊成員@Ian?Lance?Taylor,也表態(tài):目前尚未做出任何決定,也不可能在短期內(nèi)做出任何決定,可以認(rèn)為這個提案基本鴿了,今天這篇文章就是給大家同步目前的情況2023-11-11