Go設計模式之享元模式講解和代碼示例
Go 享元模式講解和代碼示例
概念示例
在游戲 《反恐精英》 中, 恐怖分子和反恐精英身著不同類型的衣物。 為了簡便起見, 我們就假設雙方都各有一種服裝類型。 服裝對象嵌入在玩家對象之中, 如下所示。
下面是玩家的結構體。 我們可以看到, 服裝對象是嵌入在玩家結構體之中的:
type player struct { dress dress playerType string // 可為 T 或 CT lat int long int }
假設目前有 5 名恐怖分子和 5 名反恐精英, 一共是 10 名玩家。 那么關于服裝, 我們就有兩個選項了。
- 10 個玩家對象各自創(chuàng)建不同的服裝對象, 并將其嵌入。 總共會創(chuàng)建 10 個服裝對象。
- 我們創(chuàng)建兩個服裝對象:
- 單一恐怖分子服裝對象: 其將在 5 名恐怖分子之間共享。
- 單一反恐精英服裝對象: 其將在 5 名反恐精英之間共享。
你可以看到, 方法 1 中我們總共創(chuàng)建了 10 個服裝對象; 方法 2 中則只有 2 個服裝對象。 第二種方法, 就是我們所遵循的享元設計模式。 我們所創(chuàng)建的 2 個服裝對象被稱為是享元對象。
享元模式會從對象中提取出公共部分并創(chuàng)建享元對象。 這些享元對象 (服裝) 隨后可在多個對象 (玩家) 中分享。 這極大地減少了服裝對象的數量, 更棒的是即便你創(chuàng)建了更多玩家, 也只需這么兩個服裝對象就足夠了。
在享元模式中, 我們會將享元對象存儲在 map 容器中。 每當創(chuàng)建共享享元對象的其他對象時, 都會從 map 容器中獲取享元對象。
下面讓我們來看看此類安排的內部狀態(tài)和外部狀態(tài):
- 內部狀態(tà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í)行結果
DressColorType: tDress
DressColor: red
DressColorType: ctDress
DressColor: green
到此這篇關于Go設計模式之享元模式講解和代碼示例的文章就介紹到這了,更多相關Go 享元模式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解Go如何基于現有的context創(chuàng)建新的context
在?Golang?中,context?包提供了創(chuàng)建和管理上下文的功能,那么在GO語言中如何基于現有的context創(chuàng)建新的context,下面小編就來和大家詳細聊聊2024-01-01