Go設(shè)計(jì)模式之享元模式講解和代碼示例
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)于服裝, 我們就有兩個(gè)選項(xiàng)了。
- 10 個(gè)玩家對象各自創(chuàng)建不同的服裝對象, 并將其嵌入。 總共會(huì)創(chuàng)建 10 個(gè)服裝對象。
- 我們創(chuàng)建兩個(gè)服裝對象:
- 單一恐怖分子服裝對象: 其將在 5 名恐怖分子之間共享。
- 單一反恐精英服裝對象: 其將在 5 名反恐精英之間共享。
你可以看到, 方法 1 中我們總共創(chuàng)建了 10 個(gè)服裝對象; 方法 2 中則只有 2 個(gè)服裝對象。 第二種方法, 就是我們所遵循的享元設(shè)計(jì)模式。 我們所創(chuàng)建的 2 個(gè)服裝對象被稱為是享元對象。
享元模式會(huì)從對象中提取出公共部分并創(chuàng)建享元對象。 這些享元對象 (服裝) 隨后可在多個(gè)對象 (玩家) 中分享。 這極大地減少了服裝對象的數(shù)量, 更棒的是即便你創(chuàng)建了更多玩家, 也只需這么兩個(gè)服裝對象就足夠了。
在享元模式中, 我們會(huì)將享元對象存儲(chǔ)在 map 容器中。 每當(dāng)創(chuàng)建共享享元對象的其他對象時(shí), 都會(huì)從 map 容器中獲取享元對象。
下面讓我們來看看此類安排的內(nèi)部狀態(tài)和外部狀態(tài):
- 內(nèi)部狀態(tài): 內(nèi)部狀態(tài)的服裝可在多個(gè)恐怖分子和反恐精英對象間共享。
- 外部狀態(tài): 玩家位置和玩家所使用的武器就是外部狀態(tài), 因?yàn)槠湓诿總€(gè)對象中都是不同的。
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è)計(jì)模式之享元模式講解和代碼示例的文章就介紹到這了,更多相關(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-01
利用golang和shell計(jì)算一個(gè)字符串的md5值
這篇文章主要介紹了如何利用golang和shell計(jì)算一個(gè)字符串的md5值,我們先用shell來計(jì)算一下,再去判斷golang計(jì)算的md5值是否正確,文中有詳細(xì)的圖文介紹,需要的朋友可以參考下2024-03-03
Go1.20最新資訊go?arena手動(dòng)管理內(nèi)存鴿了
由于過于繁雜,Go?核心團(tuán)隊(duì)成員@Ian?Lance?Taylor,也表態(tài):目前尚未做出任何決定,也不可能在短期內(nèi)做出任何決定,可以認(rèn)為這個(gè)提案基本鴿了,今天這篇文章就是給大家同步目前的情況2023-11-11
go語言channel實(shí)現(xiàn)多核并行化運(yùn)行的方法
這篇文章主要介紹了go語言channel實(shí)現(xiàn)多核并行化運(yùn)行的方法,實(shí)例分析了channel實(shí)現(xiàn)多核并行化運(yùn)行的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03

