欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go設(shè)計模式之享元模式講解和代碼示例

 更新時間:2023年06月28日 08:22:42   作者:demo007x  
享元是一種結(jié)構(gòu)型設(shè)計模式,它允許你在消耗少量內(nèi)存的情況下支持大量對象,模式通過共享多個對象的部分狀態(tài)來實現(xiàn)上述功能,換句話來說,享元會將不同對象的相同數(shù)據(jù)進行緩存以節(jié)省內(nèi)存,本文就將通過代碼示例給大家詳細(xì)介紹一下享元模式

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)文章

  • Golang你一定要懂的連接池實現(xiàn)

    Golang你一定要懂的連接池實現(xiàn)

    這篇文章主要介紹了Golang你一定要懂的連接池實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 詳解Go如何基于現(xiàn)有的context創(chuàng)建新的context

    詳解Go如何基于現(xiàn)有的context創(chuàng)建新的context

    在?Golang?中,context?包提供了創(chuàng)建和管理上下文的功能,那么在GO語言中如何基于現(xiàn)有的context創(chuàng)建新的context,下面小編就來和大家詳細(xì)聊聊
    2024-01-01
  • 利用golang和shell計算一個字符串的md5值

    利用golang和shell計算一個字符串的md5值

    這篇文章主要介紹了如何利用golang和shell計算一個字符串的md5值,我們先用shell來計算一下,再去判斷golang計算的md5值是否正確,文中有詳細(xì)的圖文介紹,需要的朋友可以參考下
    2024-03-03
  • Go1.20最新資訊go?arena手動管理內(nèi)存鴿了

    Go1.20最新資訊go?arena手動管理內(nèi)存鴿了

    由于過于繁雜,Go?核心團隊成員@Ian?Lance?Taylor,也表態(tài):目前尚未做出任何決定,也不可能在短期內(nèi)做出任何決定,可以認(rèn)為這個提案基本鴿了,今天這篇文章就是給大家同步目前的情況
    2023-11-11
  • go語言channel實現(xiàn)多核并行化運行的方法

    go語言channel實現(xiàn)多核并行化運行的方法

    這篇文章主要介紹了go語言channel實現(xiàn)多核并行化運行的方法,實例分析了channel實現(xiàn)多核并行化運行的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • GoLang 中的隨機數(shù)的示例代碼

    GoLang 中的隨機數(shù)的示例代碼

    本篇文章主要介紹了GoLang 中的隨機數(shù)的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Go中時間與時區(qū)問題的深入講解

    Go中時間與時區(qū)問題的深入講解

    go語言中如果不設(shè)置指定的時區(qū),通過time.Now()獲取到的就是本地時區(qū),下面這篇文章主要給大家介紹了關(guān)于Go中時間與時區(qū)問題的相關(guān)資料,需要的朋友可以參考下
    2021-12-12
  • Go單元測試工具gomonkey的使用

    Go單元測試工具gomonkey的使用

    本文主要介紹了Go單元測試工具gomonkey的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • goland中npm無法使用的問題及解決

    goland中npm無法使用的問題及解決

    這篇文章主要介紹了goland中npm無法使用的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Golang?并發(fā)下的問題定位及解決方案

    Golang?并發(fā)下的問題定位及解決方案

    由于?gin-swagger?是并發(fā)執(zhí)行的,?輸出的日志本身是錯位,這就導(dǎo)致無法定義是哪一個結(jié)構(gòu)體缺少?tag?導(dǎo)致的,這篇文章主要介紹了Golang?并發(fā)下的問題定位及解決方案,需要的朋友可以參考下
    2022-03-03

最新評論