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?chassis云原生微服務(wù)開發(fā)框架應(yīng)用編程實戰(zhàn)
這篇文章主要為大家介紹了Go?chassis云原生微服務(wù)開發(fā)框架應(yīng)用編程實戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-08-08
GoLang協(xié)程庫libtask學(xué)習(xí)筆記
libtask一個C語言的協(xié)程庫,是go語言的前身很早期的原型. 測試機器是我的mac air 安裝的centos虛擬機(只有一個核), 代碼沒有采用任何優(yōu)化,只是使用默認(rèn)配置2022-12-12
在ubuntu下安裝go開發(fā)環(huán)境的全過程
Go語言是谷歌公司開發(fā)的編程語言,雖然安裝和配置go很簡單,但是很多初學(xué)者在第一次安裝go環(huán)境時會遇到各種坑,下面這篇文章主要給大家介紹了關(guān)于在ubuntu下安裝go開發(fā)環(huán)境的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2022-08-08

